Entity Framework细节追踪
小分享:我有几张阿里云优惠券,用券购买或者升级阿里云相应产品最多可以优惠五折!领券地址:https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=ohmepe03
< hr />
为了加深对EF特性的了解,so,写了一些测试代码。测试结果也许对实际项目没什么用处,但是对理解EF的相关机制还是有一定帮助的。本文可能会不定期更新(加入新的测试用例=。=)。
一、事务
直接看代码。
1、所有SaveChange包裹在一个TransactionScope里面。
1 [TestMethod] 2 public void TestMethod1() 3 { 4 using (var entities = new SysProcessEntities()) 5 { 6 using (TransactionScope scope = new TransactionScope()) 7 { 8 try 9 { 10 var test = entities.SysUser.Where(o => o.OrganizationID == 1).ToList(); 11 var test2 = entities.SysRole.ToList(); 12 13 test[0].Code = "admin1"; 14 test2[0].Name = "dddd"; 15 entities.SaveChanges(); 16 17 test[0].Code = "admin"; 18 test2[0].Name = "全功能"; 19 entities.SaveChanges(); 20 21 scope.Complete(); 22 } 23 catch (Exception e) 24 { 25 26 } 27 } 28 } 29 }
结果:
2、在1的基础上去掉TransactionScope
1 [TestMethod] 2 public void TestMethod1() 3 { 4 using (var entities = new SysProcessEntities()) 5 { 6 var test = entities.SysUser.Where(o => o.OrganizationID == 1).ToList(); 7 var test2 = entities.SysRole.ToList(); 8 9 test[0].Code = "admin1"; 10 test2[0].Name = "dddd"; 11 entities.SaveChanges(); 12 13 test[0].Code = "admin"; 14 test2[0].Name = "全功能"; 15 entities.SaveChanges(); 16 } 17 }
结果:
3、注释掉2的第9行和第13行,检查单独的一条语句是否自带事务。
1 [TestMethod] 2 public void TestMethod1() 3 { 4 using (var entities = new SysProcessEntities()) 5 { 6 var test = entities.SysUser.Where(o => o.OrganizationID == 1).ToList(); 7 var test2 = entities.SysRole.ToList(); 8 9 //test[0].Code = "admin1"; 10 test2[0].Name = "dddd"; 11 entities.SaveChanges(); 12 13 //test[0].Code = "admin"; 14 test2[0].Name = "全功能"; 15 entities.SaveChanges(); 16 } 17 }
结果:
4、直接写Sql-"update [SysProcess].[dbo].[SysRole] set [name]='全功能' where ID=1",在查询分析器中执行,结果:
5、将1改为跨数据库
1 [TestMethod] 2 public void TestMethod1() 3 { 4 using (TransactionScope scope = new TransactionScope()) 5 { 6 try 7 { 8 using (var entities = new SysProcessEntities()) 9 { 10 var test = entities.SysUser.Where(o => o.OrganizationID == 1).ToList(); 11 var test2 = entities.SysRole.ToList(); 12 13 test[0].Code = "admin1"; 14 test2[0].Name = "dddd"; 15 entities.SaveChanges(); 16 17 test[0].Code = "admin"; 18 test2[0].Name = "全功能"; 19 entities.SaveChanges(); 20 } 21 using (var entities = new DistributionEntities()) 22 { 23 var test = entities.VIPCard.ToList(); 24 test[0].Sex = true; 25 entities.SaveChanges(); 26 } 27 28 scope.Complete(); 29 } 30 catch (Exception e) 31 { 32 string msg = e.Message; 33 } 34 } 35 }
结果:
于是整个世界美好了……
二、AsNoTracking
注意AsNoTracking要写在最终返回数据的那行代码中才有用,看代码:
[TestMethod] public void TestMethod9() { using (var entities = new SysProcessEntities()) { var ubs = entities.UserBrand.AsNoTracking(); ).AsNoTracking(); var brands = from ub in ubs from ob in obs where ub.BrandID == ob.BrandID select ub.BrandID; var test = entities.ProBrand.Where(b => brands.Contains(b.ID)).ToList(); Assert.AreEqual(EntityState.Detached, entities.Entry(test[]).State); } }
结果:
so,using之中应该这么写:
var ubs = entities.UserBrand; ); var brands = from ub in ubs from ob in obs where ub.BrandID == ob.BrandID select ub.BrandID; var test = entities.ProBrand.Where(b => brands.Contains(b.ID)).AsNoTracking().ToList(); Assert.AreEqual(EntityState.Detached, entities.Entry(test[]).State);
三、DbSet.Local
继续看代码:
1、
public void TestMethod10() { var entities = new SysProcessEntities(); var t1 = entities.ProBoduan.ToList(); var t2 = entities.ProBoduan.ToList(); Assert.AreEqual(t1[],t2[]); }
大家以为t1[0]是否等于t2[0]?答案是true。可是作为引用类型,我并没有重载它的Equals方法,照理应该为false才对呀。修改下测试代码:
public void TestMethod10() { var entities = new SysProcessEntities(); var t1 = entities.ProBoduan.ToList(); var t2 = entities.ProBoduan.ToList(); ].Name; t1[].Name = "随便取个名用来测试"; Assert.AreEqual(name, t2[].Name); }
结果:。可知,t1[0]和t2[0]指向的是同一个对象,即t1和t2指向同一个数组地址,也就是entities.ProBoduan.Local指向的地址。不过数据库中,仍执行了两次取数操作。
2、then,加入AsNoTracking试试看:
public void TestMethod10() { var entities = new SysProcessEntities(); var t1 = entities.ProBoduan.AsNoTracking().ToList(); var t2 = entities.ProBoduan.AsNoTracking().ToList(); ].Name; t1[].Name = "随便取个名用来测试"; Assert.AreEqual(name, t2[].Name); //true,t1的更改不影响t2,表明t1和t2指向不同地址 }
此时entities.ProBoduan.Local.Count为0。
3、
public void TestMethod10() { var entities = new SysProcessEntities(); var t2 = entities.ProBoduan.FirstOrDefault(); var t1 = entities.ProBoduan.ToList(); }
将第4行和第6行换下位置。
public void TestMethod10() { var entities = new SysProcessEntities(); var t1 = entities.ProBoduan.ToList(); var count1 = entities.ProBoduan.Local.Count;//3 var t2 = entities.ProBoduan.FirstOrDefault(); }
四、AutoDetectChangesEnabled & ValidateOnSaveEnabled
public void TestMethod9() { using (var entities = new SysProcessEntities()) { entities.Configuration.AutoDetectChangesEnabled = false; var ubs = entities.UserBrand; ); var brands = from ub in ubs from ob in obs where ub.BrandID == ob.BrandID select ub.BrandID; var test = entities.ProBrand.Where(b => brands.Contains(b.ID)).ToList(); ]).State; test[].Description = "ggggg"; ]).State; entities.ProBrand.Remove(test[]); } }
t1、t2皆为EntityState.Unchanged,原因是entities.Configuration.AutoDetectChangesEnabled = false;若设为true,那么t2将为EntityState.Modified。注意此项设置对Added和Deleted没影响。当我们循环Add大批量数据到上下文中时,设为false将对性能有非常大的提升;该属性设置对循环修改已跟踪实体的属性(entity.Property = XXXX)关系不大,大批量修改已跟踪实体的属性的效率我测试过,非常快(不管是true还是false;当然设为false,然后修改实体属性,没什么意义)。
猜测:ValidateOnSaveEnabled表示在SaveChanges()时是否根据映射文件等判断实体是否符合规则(如Key是否被改变,默认已跟踪实体是不能手动改变Key值的等),以后测试!
转载请注明本文出处:http://www.cnblogs.com/newton/archive/2013/06/03/3115603.html
参考页面:.html
Entity Framework细节追踪的更多相关文章
- Asp.Net MVC 模型(使用Entity Framework创建模型类) - Part.1
这篇教程的目的是解释在创建ASP.NET MVC应用程序时,如何使用Microsoft Entity Framework来创建数据访问类.这篇教程假设你事先对Microsoft Entity Fram ...
- Asp.Net MVC 模型(使用Entity Framework创建模型类)
这篇教程的目的是解释在创建ASP.NET MVC应用程序时,如何使用Microsoft Entity Framework来创建数据访问类.这篇教程假设你事先对Microsoft Entity Fram ...
- 使用工具追踪Entity Framework生成的SQL
学习entity framework期间收集的文章,转自http://www.cnblogs.com/hiteddy/archive/2011/10/01/Difference_among_IQuer ...
- 被Entity Framework Core的细节改进震撼了一下
今天用 SQL Server Profiler 查看 Entity Framework Core 生成的 SQL 语句时,突然发现一个细节改进,并且被它震撼了一下: exec sp_executesq ...
- "Entity Framework数据插入性能追踪"读后总结
园友莱布尼茨写了一篇<Entity Framework数据插入性能追踪>的文章,我感觉不错,至少他提出了问题,写了出来,引起了大家的讨论,这就是一个氛围.读完文章+评论,于是我自己也写了个 ...
- Entity Framework 6 Recipes 2nd Edition(13-5)译 -> 使POCO的修改追踪更高
问题 你正在使用POCO,你想提高修改跟踪的性能,同时使内存消耗更少.另外,你想通过EF的CodeFirst方式来实现. 解决方案 假设你有一个关于Account(帐户)和相关的Payments(支付 ...
- Programming Entity Framework 翻译(1)-目录
1. Introducing the ADO.NET Entity Framework ado.net entity framework 介绍 1 The Entity Relationship Mo ...
- Entity Framework Core 2.0 入门简介
不多说废话了, 直接切入正题. EF Core支持情况 EF Core的数据库Providers: 此外还即将支持CosmosDB和 Oracle. EFCore 2.0新的东西: 查询: EF.Fu ...
- Entity Framework Core 2.0 入门
该文章比较基础, 不多说废话了, 直接切入正题. 该文分以下几点: 创建Model和数据库 使用Model与数据库交互 查询和保存关联数据 EF Core支持情况 EF Core的数据库Provide ...
随机推荐
- 利用jink的驱动软件j-flash 合并两个hex的方法,bootloader+app
由于前几天要给工厂app和bootloader的hex的文件,网上很多都是bin的合并方法,bin的方法不再赘述,相信大家都能找到,现在将hex合并的方法写下来: 第一步:先打开第一个hex文件, 第 ...
- 了解 : 怎么处理jobbox status drop down list roll back
that.onStatusEnumChange = function (toStatus) { //设计理念是当completed 和 rejected 的状态下,是无法换状态 if (toStatu ...
- 关于ImageLoader的一些东西
网络图片异步加载 其实有关图片加载存在这样一个问题,图片的下载始终是一个耗时的操作,这个时候如果把图片加载放在主线程中话的是不明智的,模拟一个这样的场景, 假如在一个listview或Recycler ...
- GPU渲染管线概述
1.顶点着色器 顶点着色器是流水线的第一个阶段,它的输入来自于CPU.顶点着色器的处理单位是顶点,也就是说输入进来的每个顶点都会调用一次顶点着色器. 顶点着色器需要完成的工作主要有:坐标变换和逐顶点光 ...
- 快速排序算法javascript实现
function quicksort(arr){ function q(start,end){ if(start>=end){return;} var pivot = start, temp = ...
- golang中的rpc包用法
RPC,即 Remote Procedure Call(远程过程调用),说得通俗一点就是:调用远程计算机上的服务,就像调用本地服务一样. 我所在公司的项目是采用基于Restful的微服务架构,随着微服 ...
- asp.net mvc源码分析-Route的GetRouteData
我知道Route这里东西应该算路由,这里把它放到mvc里面有些不怎么合适,但是我想大家多数遇到路由都是在mvc的时候吧.首先我们还是来看看GetRouteData方法吧 [csharp] public ...
- 转换器2:ThinkPhp模板转Django模板
前天写了个<ThinkPhp模板转Flask模板> 居然被同事鄙视了,原因是他用Django,我用Flask,为了避免被他继续安利Django的强大.我决定写一个Django模板转换器. ...
- json串拼接模版
var jsonarr = new Array;; jsonstr = '{' + '"objuid":' + '"' + abp.common.json2string( ...
- Python全栈开发——Linux命令学习
Linux -- 一切皆文件 pwd: 查看当前所在目录 '/' :根目录 cd : 切换目录 eg.cd / 切换到根目录 ls:查看当前根目录下有几块盘.几个文件 ls -l:查看详细信 ...