博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Entity Framework中的Identity map和Unit of Work模式
阅读量:7095 次
发布时间:2019-06-28

本文共 2113 字,大约阅读时间需要 7 分钟。

阅读目录:

一、什么是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
GetStudents(){ List
result1; List
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.

 

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

 

从这里,得出的结论是:

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

转载地址:http://rdxql.baihongyu.com/

你可能感兴趣的文章
解决ArcGIS10.3属性表中文乱码问题
查看>>
《剑指offer》-青蛙跳台阶II
查看>>
OpenCV +Python 制作画板
查看>>
centos7+redis+php环境配置
查看>>
15.5. Json 内容展示
查看>>
Linux上的free命令详解
查看>>
吐槽一些技术想法和事情
查看>>
如何运行Hadoop自带的例子
查看>>
SAP HUM 如何看哪些HU还在923包装区尚未上架?
查看>>
sysresv
查看>>
SQL SERVER 重组含有特殊字符的索引时遇到“关键字 'with' 附近有语法错误.”...
查看>>
阿里巴巴跨物理界招人,世界级音频专家冯津伟入职人工智能团队iDST
查看>>
全球第四大航空南方航空与阿里云合作,成首家云上航空公司
查看>>
[20170727]library cache: mutex X.txt
查看>>
Shell 起停脚本
查看>>
[20171203]平均长度和虚拟列.txt
查看>>
LIBRARY_PATH和LD_LIBRARY_PATH环境变量的区别
查看>>
java | HttpsURLConnection 实现https请求
查看>>
.Net自写Task进程监控程序
查看>>
75篇关于Tomcat源码和机制的文章
查看>>