1. 数据库自关联,如 树 ,自关联,不能强制外键约束, 否则,一条数据也插入不进去。
2.NBearLite并不是ORM ,而是一个比 NBear 更轻量的 SQL 语法生成器, 再加上 对象映射器(Mapping), 这是两个不同的产品, NBear 的对象装载用的是 DataTable ,效率很快, NBearLite 里装载对象用了 Emit 反射发出,在我测试的过程中,用 Mapping 的 ObjectConvertor 比反射要慢 15 倍。
Database db
=
new
Database(
"
dbo
"
);
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> 存储数据的 实体。 如下:
public
partial
class
StateEntity : NBearLite.ActiveRecord
<
StateEntity
>
, INBModal
{
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 不受限制.