Ado.Net Entity Framework一如微软其它产品,用起来相当方便,基本可以无师自通。可“自通”背后也隐藏了不少陷阱,比如它正常情况下的更新模式就是如此:

var db = new DBEntities();  //Ado.net Entites
var section= db.Sections.First(s => s.SectionNo.Equals(sectionNo));
section.Name = "人事";
db.SaveChanges():

  这会导致每次更新一条记录,必须先将其查询出来。看SQL Profiler后,发现一个简单的更新要进行两次数据库连接操作!这是我们无法接受的。其实,AEF这样设计,是沿袭了过去DataSet数据集的思路,即认为所有数据源的数据,都会在内存中映射拷贝。而实际上,这种处理除了一些小程序,是不现实的。

  网上也有很多关于如何避免更新前查询的方案,但个人感觉都不太完善。实际上,Ado.Net Entity较DataSet,提供了相当的扩展性,我们可以新建包含要修改属性的实体,并响应其PropertyChanged事件,将相应属性状态标志设为修改过,Ado.Net Entity Framework便会老老实实地生成我们想要的SQL Update语句。

var db = new DBEntities();  //Ado.net Entites

//创建新实体并附加到实体集中,要初始化主键
var section = new Section { SectionNo = sectionNo };
db.Sections.Attach(section);

//获取实体状态监视器
var state = db.ObjectStateManager.GetObjectStateEntry(section); 

//监听属性更改
section.PropertyChanged += (o, e) => state.SetModifiedProperty(e.PropertyName);

//设置属性并更新
section.Name = "人事";
section.LeaderID = "zzz";
db.SaveChanges();

  遗憾的是,在New实体时,没有一个构造函数让我们直接指定此实体只用于更新。目前对于监听属性更改的代码,我们只能用扩展方法封装了。理想的是ObjectContext有一个CreateObjectToModify<T>(object key)方法,但目前AEF还不能自动根据传入实体类型,设置主键并自动附加到实体集中,这功能实现起来并不难,大概没想到吧。

  另外,使用AEF还有个问题令人恼火,它没法识别自动生成日期时间的字段,听说还得手工改SSDL,那还不如在业务逻辑层设置日期呢。希望下一代AEF,微软能让大家感觉到更给力,这样才能让自己的SQL Server卖得更好。

posted on 2011-02-20 14:04  小城故事  阅读(3766)  评论(14编辑  收藏  举报