新问题新方法:在Entity Framework中实现指定字段更新
又来一篇,大家也许都嫌烦了。但是写博客既能提高自己,又能帮助别人,而且每次写的过程中和发布出来之后都有收获,真是太赚了!麻烦大家忍一忍吧。
言归正题,在之前的一篇随笔“准备用Entity Framework实现数据的按需更新”中,我们实现了按需更新,但和这里的指定字段更新的应用场景不一样。
之前的按需更新的应用场景是:把需要更新与不需要更新的数据都给Entity Framework,由EF自己判断实际需要更新哪些。
现在的应用场景是:我明确知道要更新哪个字段,让EF做的只是更新这个操作,其他不用操心。
下面我们通过一个比喻来比较一下两者的区别。
比如我有一辆车想在汽车修理店更换一些部件。我把车停在车库里,来到修理间。这时,我就不能再直接接触这部车,必须通过修理间的工作人员。工作人员给我一个汽车模型,我有任何更换部件的想法,只能通过这个模型告诉他。
对应于第一种按需更新的场景,我不知道汽车需要实际更换哪些部件,我只知道更换后应该是什么样的。
流程是:
1. 告诉工作人员车牌号码,让他按照我放在车库中的汽车,制作一个一模一样的模型。
2. 工作人员把制作好的模型交给我。
3. 我在这个汽车模型的基础上修改成我想要的样子(但我不知道哪些部件要换,哪些部件不要换)。
4. 把修改好的汽车模型交给工作人员,让他去修理就行了。
5. 我悠然自得地去逛街,不用操心任何事。
对应于第二种根据指定字段更新的场景,我要更换前车灯,汽车修理店你不用管前车灯有没有坏,我就是要换,就是想让你们挣钱。
流程是:
1. 我随手从旁边拿了一个空汽车模型,修改为我想要的前车灯。
2. 把这个汽车模型交给工作人员,让他去修理就行了。
3. 我悠然自得地去逛街,不用操心任何事。
对于第二种场景,如果我们采用第一种场景的操作流程,工作人员累,效率低,费用自然也高。用第二个流程是必然的选择。
今天,我们终于找到了针对第二个流程的解决方法。
比如,我们要更新某个Blog的上次更新时间,我们只需要:
1. 新建一个Blog实体对象,告诉他要更新的Blog的ID以及“上次更新时间”。
2. 把这个实体对象交给Entity Framework,让他完成更新。
代码如下:
public void UpdateBlogCoinfigLastUpdatedTest()
{
using (BlogDbContext context = new BlogDbContext())
{
var blog = new Blog() { BlogID = 0, LastModified = DateTime.Now };
context.BlogConfigs.Attach(blog);
var stateEntry = ((IObjectContextAdapter)context).ObjectContext.
ObjectStateManager.GetObjectStateEntry(blog);
stateEntry.SetModifiedProperty("LastUpdated");
context.SaveChanges();
}
}
EF生成的SQL语句如下:
exec sp_executesql N'update [dbo].[blog_Config]
set [LastUpdated] = @0
where ([BlogID] = @1)
',N'@0 datetime2(7),@1 int',@0='2011-04-06 14:12:28.2129938',@1=0
秘密就藏在ObjectContext中,通过正常的方式不能得到context的ObjectContext属性。
幸运的是,园子里的大侠已经将一本秘籍流传于江湖,借助这本秘籍,我们才为这个新问题找到了新方法。在这里感谢LingzhiSun大侠!