NBear设计笔记

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<stringobject> _dict = new Dictionary<stringobject>();

        [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<stringobject> 比反射还慢? 不理解。泛型吗 ? 我换成 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 不受限制.

 

posted @ 2009-05-18 19:24  NewSea  阅读(607)  评论(0编辑  收藏  举报