NBear设计笔记
1. 数据库自关联,如 树 ,自关联,不能强制外键约束, 否则,一条数据也插入不进去。
2.NBearLite并不是ORM ,而是一个比 NBear 更轻量的 SQL 语法生成器, 再加上 对象映射器(Mapping), 这是两个不同的产品, NBear 的对象装载用的是 DataTable ,效率很快, NBearLite 里装载对象用了 Emit 反射发出,在我测试的过程中,用 Mapping 的 ObjectConvertor 比反射要慢 15 倍。
Console.ReadKey();
var ss = StateEntity.FindById("010");
{
Stopwatch wth = new Stopwatch();
wth.Start();
for (int i = 0; i < 100; i++)
{
var r = ObjectConvertor.ToObject<DataRow>(ss);
}
wth.Stop();
Console.WriteLine("NB: " + wth.ElapsedTicks );
}
var ddd = ObjectConvertor.ToObject<DataRow>(ss);
{
Stopwatch wth = new Stopwatch();
wth.Start();
for (int i = 0; i < 100; i++)
{
DataTable dtb = new DataTable();
foreach (PropertyInfo item in ss.GetType().GetProperties())
{
dtb.Columns.Add(item.Name);
}
DataRow dr = dtb.NewRow();
foreach (PropertyInfo item in ss.GetType().GetProperties())
{
dr[item.Name] = item.GetValue(ss,null);
}
}
wth.Stop();
Console.WriteLine("Reflect: " + wth.ElapsedTicks);
}
{
Stopwatch wth = new Stopwatch();
wth.Start();
for (int i = 0; i < 100; i++)
{
DataTable dtb = new DataTable();
foreach (PropertyInfo item in ss.GetType().GetProperties())
{
dtb.Columns.Add(item.Name);
}
DataRow dr = dtb.NewRow();
foreach (PropertyInfo item in ss.GetType().GetProperties())
{
dr[item.Name] = item.FastGetValue(ss);
}
}
wth.Stop();
Console.WriteLine("Fast t: " + wth.ElapsedTicks);
}
测试结果:
NB: 315023
Reflect: 18563
Fast t: 251098
dict t: 20955
NB 是 NbearLite 1.0.2.5 里提供的方法,内部是用 Emit 实现的。
Fast t: 是 http://fastreflectionlib.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=22299#ReleaseFiles 提供的开源 反射组件。
Dict t: 是一个用 Dictionary<string, object> 存储数据的 实体。 如下:
{
private Dictionary<string, object> _dict = new Dictionary<string, object>();
[PrimaryKey()]
public string ID { get { return ValueProc.Get<string>(_dict["ID"]); } set { _dict["ID"] = ValueProc.Get<string>(value); } }
public string Name { get { return ValueProc.Get<string>(_dict["Name"]); } set { _dict["Name"] = ValueProc.Get<string>(value); } }
public void SetValue(string key, object Value)
{
this._dict[key] = Value;
}
public object GetValue(string key)
{
return this._dict[key];
}
public string[] GetKeys()
{
return this._dict.Keys.ToArray();
}
static StateEntity()
{
Initialize(new Database("dbo"), dbo.State, dbo.State.ID, null);
}
}
普通的 Reflect 更快。 猜测:
Fast Reflector 用了缓存, 当循环次数少的时候,看单次执行效率, 它执行的效率比较差。
从我得到的资料, Emit 应该比普通的 Reflect 更快。 跟 Fast Reflector 一样。它也很慢。
Dictionary<string, object> 比反射还慢? 不理解。泛型吗 ? 我换成 NameValueCollection 还是一样。换成 Hashtable 性能比反射好一些(18000)。看来, 泛型的性能一般。 其它的更不行。
测试不能仅仅玩 缓存。 那样的话, 就没为了测试而测试了。有更准的测试欢迎拍砖。
3. 我下载的最新版的 NBearLite 1.0.2.5 , SQLite 查询前导符是 “?” , 是不对的, 应该是 “@” 。
4.Sqlserver 里的 Bit ,虽然对应到 C# 里是 bool , 但是 NBearLite 是对应不上的。 因为C# 里没有把 bit 转换为 bool 的方法 。 改用 int 吧。
另外.SqlServer 里 varbinary 对应到 C# 里是 byte[] ,但是 NBearLite.Mappint.ObjectCovnertor 不能转换它.
5.E:\MyApp\MyWebTradeSln\nb1025\NBearLite\NBearLite\DbProviders\SqlServer\SqlServerDbProviderOptions.cs
GetSelectLastInsertAutoIncrementIDSql 函数应该为:
return "SELECT @@IDENTITY";
当有插入触发器的时候,SCOPE_IDENTITY()会返回 Null 值 . MSDN说 : SCOPE_IDENTITY 只返回插入到当前作用域中的值 .意思是说, 触发器插入在另外一个作用域.想想也是. 而 @@IDENTITY 不受限制.
作者:NewSea 出处:http://newsea.cnblogs.com/
QQ,MSN:iamnewsea@hotmail.com 如无特别标记说明,均为NewSea原创,版权私有,翻载必纠。欢迎交流,转载,但要在页面明显位置给出原文连接。谢谢。 |