小分享:我有几张阿里云优惠券,用券购买或者升级阿里云相应产品最多可以优惠五折!领券地址: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细节追踪的更多相关文章

  1. Asp.Net MVC 模型(使用Entity Framework创建模型类) - Part.1

    这篇教程的目的是解释在创建ASP.NET MVC应用程序时,如何使用Microsoft Entity Framework来创建数据访问类.这篇教程假设你事先对Microsoft Entity Fram ...

  2. Asp.Net MVC 模型(使用Entity Framework创建模型类)

    这篇教程的目的是解释在创建ASP.NET MVC应用程序时,如何使用Microsoft Entity Framework来创建数据访问类.这篇教程假设你事先对Microsoft Entity Fram ...

  3. 使用工具追踪Entity Framework生成的SQL

    学习entity framework期间收集的文章,转自http://www.cnblogs.com/hiteddy/archive/2011/10/01/Difference_among_IQuer ...

  4. 被Entity Framework Core的细节改进震撼了一下

    今天用 SQL Server Profiler 查看 Entity Framework Core 生成的 SQL 语句时,突然发现一个细节改进,并且被它震撼了一下: exec sp_executesq ...

  5. "Entity Framework数据插入性能追踪"读后总结

    园友莱布尼茨写了一篇<Entity Framework数据插入性能追踪>的文章,我感觉不错,至少他提出了问题,写了出来,引起了大家的讨论,这就是一个氛围.读完文章+评论,于是我自己也写了个 ...

  6. Entity Framework 6 Recipes 2nd Edition(13-5)译 -> 使POCO的修改追踪更高

    问题 你正在使用POCO,你想提高修改跟踪的性能,同时使内存消耗更少.另外,你想通过EF的CodeFirst方式来实现. 解决方案 假设你有一个关于Account(帐户)和相关的Payments(支付 ...

  7. Programming Entity Framework 翻译(1)-目录

    1. Introducing the ADO.NET Entity Framework ado.net entity framework 介绍 1 The Entity Relationship Mo ...

  8. Entity Framework Core 2.0 入门简介

    不多说废话了, 直接切入正题. EF Core支持情况 EF Core的数据库Providers: 此外还即将支持CosmosDB和 Oracle. EFCore 2.0新的东西: 查询: EF.Fu ...

  9. Entity Framework Core 2.0 入门

    该文章比较基础, 不多说废话了, 直接切入正题. 该文分以下几点: 创建Model和数据库 使用Model与数据库交互 查询和保存关联数据 EF Core支持情况 EF Core的数据库Provide ...

随机推荐

  1. 【PHP系列】PHP推荐标准之PSR-3,日志记录器接口

    上节聊完了PHP官方的相关代码规范,下面给大家带来了PHP系列的PHP推荐标准的另外两个,PSR-3,PSR-4. 首先,我们先来了解下PSR-3是怎么回事. PHP-FIG发布的第三个推荐规范与前两 ...

  2. JavaScript代码规范和性能整理

    性能 Js在性能方面有多要注意的地方: 避免全局查找 Js性能优化最重要的就是注意全局查找,因为作用域的查找是先找局部作用域在没有找到之后在去上一级作用域查找直到全局作用域,所以全局作用域查找的性能消 ...

  3. 怎么用php语言来做文件缓存

    使用缓存能够让我们的程序访问起来更加快速,缓存可以减少对数据库的操作,体验起来更好一些,对服务器的压力也小一些,当然服务速度很快 php文件执行完之后产生的解析完的数据,保存成静态的网页,下次打开的这 ...

  4. 编程那些事儿:如何快速地"借用"CSS

    做前端开发有时候会碰到任务紧急,需要马上写好静态页的问题.比如,设计师给你扔了一个设计稿,要你在下班之前搞定.这时候你如热锅上的蚂蚁,如果自己写css的话,时间紧张,于是上网找了一下相关模板页面,找到 ...

  5. UIScrollView 和 UICollectionView 分页效果

    UIScrollView 和 UICollectionView 分页效果 UIScrollView可以滚动显示宽度或高度大于其bounds的内容.有些时候,需要有分页效果.每一页有统一的大小,相邻无缝 ...

  6. C#7.0之ref locals and returns (局部变量和引用返回,之前欠大家的,现在补上)

    废话不多说,直接进入正题. 首先我们知道 ref关键字是将值传递变为引用传递 那么我们先来看看ref locals(ref局部变量) 列子代码如下: static void Main(string[] ...

  7. 百度地图JavascriptApi Marker平滑移动及车头指向行径方向

    相信只要是使用百度地图做实时定位服务的朋友都会遇到这个问题,在对坐标位置进行覆盖物展示的时候,会出现由于获取坐标数据时间或者两个坐标点相距过远,导致在视觉上看Marker移动就像"僵尸跳&q ...

  8. 3399: [Usaco2009 Mar]Sand Castle城堡

    3399: [Usaco2009 Mar]Sand Castle城堡 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 37  Solved: 32[Sub ...

  9. 超出父视图无法点击问题hitTest

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo; color: #c91b13 } p.p2 { margin: 0.0px 0. ...

  10. Linux实战教学笔记25:自动化运维工具之ansible (一)

    第二十五节 ansible之文件的批量分发 标签(空格分隔): Linux实战教学笔记-陈思齐 ---本教学笔记是本人学习和工作生涯中的摘记整理而成,此为初稿(尚有诸多不完善之处),为原创作品,允许转 ...