翻译的初衷以及为什么选择《Entity Framework 6 Recipes》来学习,请看本系列开篇

5-4  查询内存对象

问题

  你想使用模型中的实体对象,如果他们已经加载到上下文中,便不用与数据库发生交互。另外,你想使用Code-First来管理数据访问。

解决方案

  假设你有如图5-12所示的模型。

图5-12 一个包含Club实体对象的简单模型

  在Visual Studio中添加一个名为Recipe4的控制台应用,并确保引用了实体框架6的库,NuGet可以很好的完成这个任务。在Reference目录上右键,并选择 Manage NeGet Packages(管理NeGet包),在Online页,定位并安装实体框架6的包。这样操作后,NeGet将下载,安装和配置实体框架6的库到你的项目中。

  创建一个名为Club类,复制代码清单5-8中的属性到这个类中,创建club实体。

代码清单5-8. Club实体类

  1. public class Club
  2. {
  3. public int ClubId { get; set; }
  4. public string Name { get; set; }
  5. public string City { get; set; }
  6. }

  

  接下来,创建一个名为Recipe4Context的类,并将代码清单5-9中的代码添加到其中,并确保其派生到DbContext类。

代码清单5-9. 上下文对象Recipe4Contex

  1. 1 public class Recipe4Context : DbContext
  2. 2 {
  3. 3 public Recipe4Context()
  4. 4 : base("Recipe4ConnectionString")
  5. 5 {
  6. 6 // 禁用实体框架的模型兼容性
  7. 7 Database.SetInitializer<Recipe3Context>(null);
  8. 8 }
  9. 9
  10. 10 protected override void OnModelCreating(DbModelBuilder modelBuilder)
  11. 11 {
  12. 12 modelBuilder.Entity<Club>().ToTable("Chapter5.Club");
  13. 13 }
  14. 14
  15. 15 public DbSet<Club> Clubs { get; set; }
  16. 16 }

  接下来添加App.Config文件到项目中,并使用代码清单5-10中的代码添加到文件的ConnectionStrings小节下。

代码清单5-10. 连接字符串

  1. <connectionStrings>
  2. <add name="Recipe4ConnectionString"
  3. connectionString="Data Source=.;
  4. Initial Catalog=EFRecipes;
  5. Integrated Security=True;
  6. MultipleActiveResultSets=True"
  7. providerName="System.Data.SqlClient" />
  8. </connectionStrings>

  在这个模型中,我们有一个实体类型Club,你可以通过查询获取各种各样的俱乐部(Clubs). 我们可以通过查询DbSet的属性Local来减少与数据库的交互。它是对Club实体的包装。属性Local 公布了一个内存实体对象的动态集合(Observable Collection),与上下文对象保持同步。代码清单5-11演示了Local动态集合的用法。

代码清单5-11. DbSet对象中Local 属性的一般用法

  1.        int desertSunId;
  2.  
  3. using (var context = new Recipe4Context())
  4. {
  5. var starCity = new Club {Name = "Star City Chess Club", City = "New York"};
  6. var desertSun = new Club {Name = "Desert Sun Chess Club", City = "Phoenix"};
  7. var palmTree = new Club {Name = "Palm Tree Chess Club", City = "San Diego"};
  8.  
  9. context.Clubs.Add(starCity);
  10. context.Clubs.Add(desertSun);
  11. context.Clubs.Add(palmTree);
  12.  
  13. context.SaveChanges();
  14.  
  15. desertSunId = desertSun.ClubId;
  16. }
  17.  
  18. using (var context = new Recipe4Context())
  19. {
  20. Console.WriteLine("\nLocal Collection Behavior");
  21. Console.WriteLine("=================");
  22.  
  23. Console.WriteLine("\nNumber of Clubs Contained in Local Collection: {0}", context.Clubs.Local.Count);
  24. Console.WriteLine("=================");
  25.  
  26. Console.WriteLine("\nClubs Retrieved from Context Object");
  27. Console.WriteLine("=================");
  28. foreach (var club in context.Clubs.Take())
  29. {
  30. Console.WriteLine("{0} is located in {1}", club.Name, club.City);
  31. }
  32.  
  33. Console.WriteLine("\nClubs Contained in Context Local Collection");
  34. Console.WriteLine("=================");
  35. foreach (var club in context.Clubs.Local)
  36. {
  37. Console.WriteLine("{0} is located in {1}", club.Name, club.City);
  38. }
  39.  
  40. context.Clubs.Find(desertSunId);
  41.  
  42. Console.WriteLine("\nClubs Retrieved from Context Object - Revisted");
  43. Console.WriteLine("=================");
  44. foreach (var club in context.Clubs)
  45. {
  46. Console.WriteLine("{0} is located in {1}", club.Name, club.City);
  47. }
  48.  
  49. Console.WriteLine("\nClubs Contained in Context Local Collection - Revisted");
  50. Console.WriteLine("=================");
  51. foreach (var club in context.Clubs.Local)
  52. {
  53. Console.WriteLine("{0} is located in {1}", club.Name, club.City);
  54. }
  55.  
  56. //获取local集合的引用
  57. var localClubs = context.Clubs.Local;
  58.  
  59. // 添加一个新的 Club
  60. var lonesomePintId = -;
  61. localClubs.Add(new Club
  62. {
  63. City = "Portland",
  64. Name = "Lonesome Pine",
  65. ClubId = lonesomePintId
  66. });
  67.  
  68. // 删除 Desert Sun club
  69. localClubs.Remove(context.Clubs.Find(desertSunId));
  70.  
  71. Console.WriteLine("\nClubs Contained in Context Object - After Adding and Deleting");
  72. Console.WriteLine("=================");
  73. foreach (var club in context.Clubs)
  74. {
  75. Console.WriteLine("{0} is located in {1} with a Entity State of {2}",
  76. club.Name, club.City, context.Entry(club).State);
  77. }
  78.  
  79. Console.WriteLine("\nClubs Contained in Context Local Collection - After Adding and Deleting");
  80. Console.WriteLine("=================");
  81. foreach (var club in localClubs)
  82. {
  83. Console.WriteLine("{0} is located in {1} with a Entity State of {2}",
  84. club.Name, club.City, context.Entry(club).State);
  85. }
  86.  
  87. Console.WriteLine("\nPress <enter> to continue...");
  88. Console.ReadLine();

代码清单5-11的输出如下:

  1. Local Collection Behavior
  2. =================
  3. Number of Clubs Contained in Local Collection:
  4. =================
  5. Clubs Retrieved from Context Object
  6. =================
  7. Star City Chess Club is located in New York
  8. Desert Sun Chess Club is located in Phoenix
  9. Clubs Contained in Context Local Collection
  10. =================
  11. Star City Chess Club is located in New York
  12. Desert Sun Chess Club is located in Phoenix
  13. Clubs Retrieved from Context Object - Revisted
  14. =================
  15. Star City Chess Club is located in New York
  16. Desert Sun Chess Club is located in Phoenix
  17. Palm Tree Chess Club is located in San Diego
  18. Clubs Contained in Context Local Collection - Revisted
  19. =================
  20. Star City Chess Club is located in New York
  21. Desert Sun Chess Club is located in Phoenix
  22. Palm Tree Chess Club is located in San Diego
  23. Clubs Contained in Context Object After Adding and Deleting
  24. =================
  25. Star City Chess Club is located in New York with a Entity State of Unchanged
  26. Desert Sun Chess Club is located in Phoenix with a Entity State of Deleted
  27. Palm Tree Chess Club is located in San Diego with a Entity State of Unchanged
  28. Clubs Contained in Context Local Collection After Adding and Deleting
  29. =================
  30. Star City Chess Club is located in New York with a Entity State of Unchanged
  31. Palm Tree Chess Club is located in San Diego with a Entity State of Unchanged
  32. Lonesome Pine is located in Portland with a Entity State of Added

原理

   这个示例使用Club实体对象。开始,我们从Local属性公布的动态集合中获取Club实体对象的数量。注意,图5-13没有SQL查询产生,因为一个对Local属性的查询,是不会产生针对数据库的SQL查询的。

图5-13 访问Local动态集合,不会产生一个SQL查询

  现在,结果为0,因为我们还没有通过上下文对象执行一个关于Clubs的查询。记住,Local动态集合会自动地与上下文对象保持同步。

  接下来,我们通过上下文对象在数据库中查询前面两个Club实体。并循环输出他们的名称和地点。如图5-14所示。

图5-14 查询上下文对象,总是产生一个SQL查询

  随后,我们立即循环相应的Local集合,得到了相同的结果。记住,结果集完全一样,因为Local集合自动与DbContext保持同步。如果新的实体被获取到上下文,通过这些实体,Loacal集合会被自动更新。注意,图5-15中,当访问Local集合时,没有SQL查询生成。

图5-15 访问 local集合,没有生成SQL语句

  为了进一步演示Local属性的默认行为,我们通过上下文查询获取第三个Club实体,我们又一次循环上下文对象和Local集合,同样得到了相同的结果。图5-16中,通过查询上下文对象的查询产生了一个SQL语句,图5-17中,能通查询Local集合的查询,没有产生任何SQL语句。

图5-16 查询上下文对象,总是产生一个SQL查询

图5-17  访问 local集合,没有生成SQL语句

  接下来,我们添加一个名为 Lonesone Pine Club实体到Local集合中,同时,我们从Local集合中删除Desert Sun Club. 然后我们枚举上下文对象中的Clubs,正如期望的那样,一个SQL查询产生了,如图5-18所示。

图5-18 查询上下文对象,总是产生一个SQL查询

  有趣的是,我们看到,在上下文中Desert Sun Club已经被标记为删除,但我们没有看到最新添加的Lonesome Pine Club对象。记住,Lonesome Pine Club已经被添加到上下文中,但我们还没有调用SaveChanges()方法更新到底层据库中

  然而,当我们枚举Local集合时,没有产生针对底层数据库的查询,如图5-19所示。相反,我们看到了最新添加的Lonesome Pine Club对象,但我们不再看到标记为删除的Desert Sun Club对象。 Loacl集合的默认行为是,隐藏任何标记为删除的对象,因为这些对象不于有效

图5-19  访问 local集合,没有生成SQL语句

  

  本质:访问Local集合不会产生针对底层数据库的SQL查询,访问上下中的属性集合总是会产生一个被发送到数据库中的SQL是查询

  总之,名为Local的属性公布的实体集,是一个动态的集合(Observale Collection)(译注:也有人译为,可观察的集合,但综合该对象的作用和功能来看,个人认为译为动态集合更恰当一些),它是上下文内容的一个镜像。正如本小节演示的那样,查询Local集合非常有效,因为它不会产生针对底层数据库的SQL查询。

实体框架交流QQ群:  458326058,欢迎有兴趣的朋友加入一起交流

谢谢大家的持续关注,我的博客地址:http://www.cnblogs.com/VolcanoCloud/

《Entity Framework 6 Recipes》中文翻译系列 (24) ------ 第五章 加载实体和导航属性之查询内存对象的更多相关文章

  1. 《Entity Framework 6 Recipes》中文翻译系列 (22) -----第五章 加载实体和导航属性之延迟加载

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第五章 加载实体和导航属性 实体框架提供了非常棒的建模环境,它允许开发人员可视化地使 ...

  2. 《Entity Framework 6 Recipes》中文翻译系列 (28) ------ 第五章 加载实体和导航属性之测试实体是否加载与显式加载关联实体

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-11  测试实体引用或实体集合是否加载 问题 你想测试关联实体或实体集合是否已经 ...

  3. 《Entity Framework 6 Recipes》中文翻译系列 (23) -----第五章 加载实体和导航属性之预先加载与Find()方法

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-2  预先加载关联实体 问题 你想在一次数据交互中加载一个实体和与它相关联实体. ...

  4. 《Entity Framework 6 Recipes》中文翻译系列 (25) ------ 第五章 加载实体和导航属性之加载完整的对象图和派生类型上的导航属性

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-5  加载完整的对象图 问题 你有一个包含许多关联实体的模型,你想在一次查询中, ...

  5. 《Entity Framework 6 Recipes》中文翻译系列 (26) ------ 第五章 加载实体和导航属性之延缓加载关联实体和在别的LINQ查询操作中使用Include()方法

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-7  在别的LINQ查询操作中使用Include()方法 问题 你有一个LINQ ...

  6. 《Entity Framework 6 Recipes》中文翻译系列 (27) ------ 第五章 加载实体和导航属性之关联实体过滤、排序、执行聚合操作

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-9  关联实体过滤和排序 问题 你有一实体的实例,你想加载应用了过滤和排序的相关 ...

  7. 《Entity Framework 6 Recipes》中文翻译系列 (29) ------ 第五章 加载实体和导航属性之过滤预先加载的实体集合和修改外键关联

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-13  过滤预先加载的实体集合 问题 你想过滤预先加载的实体集合,另外,你想使用 ...

  8. 《Entity Framework 6 Recipes》翻译系列 (1) -----第一章 开始使用实体框架之历史和框架简述

    微软的Entity Framework 受到越来越多人的关注和使用,Entity Framework7.0版本也即将发行.虽然已经开源,可遗憾的是,国内没有关于它的书籍,更不用说好书了,可能是因为EF ...

  9. 《Entity Framework 6 Recipes》翻译系列 (4) -----第二章 实体数据建模基础之从已存在的数据库创建模型

    不知道对EF感兴趣的并不多,还是我翻译有问题(如果是,恳请你指正),通过前几篇的反馈,阅读这个系列的人不多.不要这事到最后成了吃不讨好的事就麻烦了,废话就到这里,直奔主题. 2-2 从已存在的数据库创 ...

随机推荐

  1. PHP开发笔记:二维数组根据某一项来进行排序

    比如说我们现在有一个二维数组: $arr = array( ‘d' => array(‘id' => 5, ‘name' => 1, ‘age' => 7), ‘b' => ...

  2. php sprintf 函数的用法

    sprintf() 函数把格式化的字符串写入变量中. arg1.arg2.++ 参数将被插入到主字符串中的百分号(%)符号处.该函数是逐步执行的.在第一个 % 符号处,插入 arg1,在第二个 % 符 ...

  3. 代码中使用StoryBoard和DoubleAnimation的方法

    TranslateTransformを対象に.DoubleAnimation型のアニメーションを使用して.TranslateTransform.Xプロパティを ”-1 * Imageコントロールの幅” ...

  4. 常用.NET库使用总结

    Json.NET 获取类实例对应的jtoken:JObject.FromObject() 获取数组实例对应的jtoken:JArray.FromObject() Json.NET将枚举转换为int R ...

  5. 【原】iOS学习之应用之间的操作

    关于应用之间的相互操作,小编一直觉得非常高大上,在一次面试中被面试官一顿暴虐,今天小编就决定学习一下!经过一顿度娘,找到一些博客,不过都比较凌乱,我就打算自己整理一下! 首先要说的是每一个APP都可以 ...

  6. 转载:Chrome调试折腾记_(1)调试控制中心快捷键详解!!!

    转载:http://blog.csdn.net/crper/article/details/48098625 大多浏览器的调试功能的启用快捷键都一致…按下F12;还是熟悉的味道;  或者直接 Ctrl ...

  7. router路由去掉#!的踩坑记

    项目中在研究去掉router#!的过程中的踩坑过程.

  8. Linux Shell中单引号、双引号、反引号的区别【转载】

    linux shell可以识别4种不同类型的引字符号: 单引号字符' 双引号字符" 反斜杠字符\ 反引号字符` 1. 单引号 ( '' )# grep Susan phonebook Sus ...

  9. Erlang error handling

    Erlang error handling Contents Preface try-catch Process link Erlang-way error handling OTP supervis ...

  10. Smart3D系列教程5之 《案例实战演练2——大区域的地形三维重建》

    一.前言 Wish3D出品的Smart3D系列教程中,前面一讲说明了小物件的照片三维重建,相信大家对建模的流程有了一定的了解.这次讲解中,我们将演示说明以一组无人机倾斜摄影照片为原始数据,通过Smar ...