Entity Framework中的Identity map和Unit of Work模式_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > Entity Framework中的Identity map和Unit of Work模式

Entity Framework中的Identity map和Unit of Work模式

 2013/8/8 3:08:16  JustRun  博客园  我要评论(0)
  • 摘要:阅读目录:一、什么是Identitymap模式二、关于Identitymap模式的验证示例三、UnitofWork模式四、总结和注意的问题一,什么是Identitymap模式Identitymap是EF获取和缓存数据的模式。Identitymap模式指的是任何数据都只会被加载一次,以map的形式缓存,以唯一的identity来再次获取这些数据。在EF中,就是在一个Context的生命周期中,所有查询过的数据都会缓存到Context的local中缓存。当再次访问这些数据的时候,就会以主键
  • 标签:Framework Map ide 模式

阅读目录:

一、什么是Identity map模式

二、关于Identity map模式的验证示例

三、Unit of Work 模式

四、总结和注意的问题

一,什么是Identity map模式

Identity map是EF获取和缓存数据的模式。
Identity map模式指的是任何数据都只会被加载一次,以map的形式缓存,以唯一的identity来再次获取这些数据。
在EF中,就是在一个Context的生命周期中,所有查询过的数据都会缓存到Context的local中缓存。当再次访问这些数据的时候,就会以主键(identity)从缓存中获取这些数据。

二,关于Identity map模式的验证示例

看看下面这段代码运行的结果:

using (var context = new SchoolContext())
{
       result1 = context.Students.ToList();
       result1[0].Age = -1;
       result2 = context.Students.ToList();

       var s1 = context.Students.First(s => s.Id == 1);
       var s2 = context.Students.First(s => s.Id == 1);
       var s3 = context.Students.First(s => s.Id == 3);
       var s4 = context.Students.First(s => s.Id == 3);

       Debug.Assert(ReferenceEquals(s1, s2));
       Debug.Assert(ReferenceEquals(s3, s4));
 }

运行之后,会发现s1和s2是同一个引用,s3和s4也是同一个引用。
原因就是在Identity map模式来说,对于唯一的主键,返回的必然是同一个对象。

再来看一个更加有趣的例子

public IEnumerable<Student> GetStudents()
{
       List<Student> result1;
       List<Student> result2;
       using (var context = new SchoolContext())
       {
           result1 = context.Students.ToList();
           result1[0].Age = -1;
           result2 = context.Students.ToList();
       }
       return result2;
}

实际的数据库中的result1[0].Age是18,如果修改Age是-1, 再次执行context.Students.ToList(), 返回数据的Age并不是数据库中的18,而是-1.

image

 

image

但是根据MiniProfiler的监控结果,EF的确访问了2次数据库

image

 

从这里,得出的结论是:

Context在一次查询结束后,得到的数据会保存到本地缓存,在提交之前对数据的修改都是在本地进行。
当再次Qeury的时候,Context中不存在的数据会放到Context中,Context已经存在的数据(即使被修改了),也不会被数据库的数据覆盖。

三. Unit of Work 模式

Unit of Work模式指的是:

所有对于context中查询得到的实体对象的数据修改,都只会在调用SaveChanges方法后,才会真正的保存到数据库中。你可以在一个Context的生命周期中,修改多个实体对象的值,然后一次提交保存。
在EF中,由于Unit of Work模式,没有办法做选择性的保存数据,只要是数据发生了改动,都会在SaveChnage方法中一并提交到数据库中保存。

四,总结和注意问题

结合这两种模式,可以看出
在一个Context的生命周期中,一个Entity只会有一个实例,任何对该实例的修改,即使这些改动没有保存到数据库中,修改都会影响到整个Context的生命周期。

注意问题:

1. 在使用EF的时候,理想的方式应该是 获取数据-> 修改数据,保存数据->获取数据……的过程。
不要在修改数据的过程中,再次请求数据,因为这些数据很可能和数据库中的数据不一致。

2. 在显示层,最好使用ViewModel, 而不要直接使用EF中Model.
比如一篇博客文章中,我只想显示前500个字给非注册用户看,如果使用Model, 不小心直接将文章内容的字段修改了,只保留了500个字,然后最后调用了SaveChange,用来保存文章的阅读数字。
这样就会导致文章内容被我不小心给丢失了。

下篇讨论如何在Asp.net MVC中实现One Context Per Request

上一篇: 动态变更Repeater控件HeaderTemplate列名 下一篇: 没有下一篇了!
发表评论
用户名: 匿名