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

简介:

阅读目录:

一、什么是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


本文转自JustRun博客园博客,原文链接:http://www.cnblogs.com/JustRun1983/p/3244790.html,如需转载请自行联系原作者



目录
相关文章
|
22天前
|
存储 供应链 搜索推荐
Spartacus product variant configuration sample data
Spartacus product variant configuration sample data
21 2
|
11月前
|
程序员 Go API
SAP QM 执行事务代码QP01,系统报错 -Material type FOOD is not defined for task list type Q-
SAP QM 执行事务代码QP01,系统报错 -Material type FOOD is not defined for task list type Q-
SAP QM 执行事务代码QP01,系统报错 -Material type FOOD is not defined for task list type Q-
在S4 key user tool里创建Custom Logic的后台实现
在S4 key user tool里创建Custom Logic的后台实现
在S4 key user tool里创建Custom Logic的后台实现
How to put S4 extension field to CRM WebUI search view in the design time
How to put S4 extension field to CRM WebUI search view in the design time
How to put S4 extension field to CRM WebUI search view in the design time
|
Java
Hybris DDIC type and its counterpart model class
Hybris DDIC type and its counterpart model class
112 0
Hybris DDIC type and its counterpart model class
SAP Spartacus org unit list当前行is-current的判定逻辑
SAP Spartacus org unit list当前行is-current的判定逻辑
110 0
SAP Spartacus org unit list当前行is-current的判定逻辑
component set load logic - why coms_pcat_bob is accessed during product search
component set load logic - why coms_pcat_bob is accessed during product search
113 0
component set load logic - why coms_pcat_bob is accessed during product search
how drop down list description is displayed by UI framework
how drop down list description is displayed by UI framework
160 0
how drop down list description is displayed by UI framework

热门文章

最新文章