问题

你想有效地获取只是用来显示不会更新的操作的实体.另外,你想用CodeFirst的方式来实现

解决方案

一个非常常见行为,尤其是网站,就是只是让用户浏览数据.大多数情况下,用户不会更新数据.在这种情况下,你可以通过避开上下文的缓存和修改跟踪来提高代码性能,你可以非常简单地使用AsNoTracking方法来实现.

让我们假设你一个应用程序来管理doctor(医生)的appointments(预约),你的模型如下图Figure 13-5.

Figure 13-5. A model for managing doctors and their appointments

 

         首先,这个例子用EFCodeFirst方式来实现.,Listing 13-6创建我们的实体类, Company, Doctor, 和Appointment.

Listing 13-6. The Company, Doctor,and Appointment.Entity Object

public class Company

{

public Company()

{

Doctors = new HashSet<Doctor>();

}

public int CompanyId { get; set; }

public string Name { get; set; }

public virtual ICollection<Doctor> Doctors { get; set; }

}

public class Doctor

{

public Doctor()

{

Appointments = new HashSet<Appointment>();

}

public int DoctorId { get; set; }

public string Name { get; set; }

public int CompanyId { get; set; }

public virtual ICollection<Appointment> Appointments { get; set; }

public virtual Company Company { get; set; }

}

public class Appointment

{

public int AppointmentId { get; set; }

public System.DateTime AppointmentDate { get; set; }

public string Patient { get; set; }

public int DoctorId { get; set; }

public virtual Doctor Doctor { get; set; }

}

接下来,在Listing 13-7,我们创建用CodeFirst方式时访问EF的途径,DbContext对象

Listing 13-7. DbContext Object

public class Recipe3Context : DbContext

{

public Recipe3Context()

: base("Recipe3ConnectionString")

{

// Disable Entity Framework Model Compatibility

Database.SetInitializer<Recipe3Context>(null);

}

protected override void OnModelCreating(DbModelBuilder modelBuilder)

{

modelBuilder.Entity<Appointment>().ToTable("Chapter13.Appointment");

modelBuilder.Entity<Company>().ToTable("Chapter13.Company");

modelBuilder.Entity<Doctor>().ToTable("Chapter13.Doctor");

}

public DbSet<Appointment> Appointments { get; set; }

public DbSet<Company> Companies { get; set; }

public DbSet<Doctor> Doctors { get; set; }

}

接下来我们在项目中添加App.Config,并把下列Listing 13-8的代码加入到ConnectionString节下

Listing 13-8. Connection String

<connectionStrings>

<add name="Recipe3ConnectionString"

connectionString="Data Source=.;

Initial Catalog=EFRecipes;

Integrated Security=True;

MultipleActiveResultSets=True"

providerName="System.Data.SqlClient" />

</connectionStrings>

为了获取Doctors和Companies并使他们不添加到上下文对象中,我们把AsNoTracking方法链接到获取实体的查询中,如Listing 13-9 那样.

Listing 13-9. Doing a Simple Query Using the AsNoTracking Method

using (var context = new Recipe3Context())

{

var company = new Company { Name = "Paola Heart Center" };

var doc1 = new Doctor { Name = "Jill Mathers", Company = company };

var doc2 = new Doctor { Name = "Robert Stevens", Company = company };

var app1 = new Appointment

{

AppointmentDate = DateTime.Parse("3/18/2010"),

Patient = "Karen Rodgers",

Doctor = doc1

};

var app2 = new Appointment

{

AppointmentDate = DateTime.Parse("3/20/2010"),

Patient = "Steven Cook",

Doctor = doc2

};

context.Doctors.Add(doc1);

context.Doctors.Add(doc2);

context.Appointments.Add(app1);

context.Appointments.Add(app2);

context.Companies.Add(company);

context.SaveChanges();

}

using (var context = new Recipe3Context())

{

Console.WriteLine("Entities tracked in context for Doctors...");

// 用AsNoTracking() 方法执行查询

context.Doctors.Include("Company").AsNoTracking().ToList();

Console.WriteLine("Number of entities loaded into context with AsNoTracking: {0}",

context.ChangeTracker.Entries().Count());//输出:0

// 不用AsNoTracking() 方法执行查询

context.Doctors.Include("Company").ToList();

Console.WriteLine("Number of entities loaded into context without AsNoTracking: {0}",

context.ChangeTracker.Entries().Count());//输出:3

}

输出结果如下:

Entities tracked in context for Doctors...

Number of entities loaded into context with AsNoTracking: 0

Number of entities loaded into context without AsNoTracking: 3

它是如何工作的

当我们把AsNoTracking方法链接上你的查询,从查询返回的结果不会被上下文跟踪.在我们的例子中,我们显示地Include了Doctor的Comanpies.

默认情况下,你的查询结果会被上下文跟踪,这使得更新和删除更容易,但是代价是付出更多的内存和CPU负载.为应用程序串连更多的对象,比如在电子商务网站上浏览产品,使用AsNoTracking选项,能节省更多的资源,使应用程序性能更高.

没有缓存一个查询结果,你每次都得为查询实例化.通常地,使修改跟踪可用,EF将不需要为一个上下文中已经存在的实例再实例化.

当你包含AsNoTracking选项(如我们的Listing 13-9),它只影响当前查询的实体.它不会影响后面的不包含AsNoTracking选项的查询,如Listing 13-9 演示的

最新文章

  1. Windows建立Cucumber和Ruby测试环境
  2. 深入理解cookies
  3. Nginx+Tomcat发布时不间断服务的提供
  4. JS手札
  5. qt 工具下的dump工具导出文档出现异常解决方案
  6. 在Windows下安装Memcached
  7. JDBC:从数据库中取数据的一个bug
  8. 【原】iOS学习46之第三方CocoaPods的安装和使用(通用方法)
  9. jquery 动态生成html后click事件不触发原因
  10. mac idea 设置
  11. iOS UIButton EdgeInsets
  12. Codevs 3287 货车运输 2013年NOIP全国联赛提高组(带权LCA+并查集+最大生成树)
  13. phonegap学习入门
  14. Git学习02 --暂存区,撤销修改,删除文件
  15. SICP 习题 (1.37)解题总结
  16. angulajs_删除功能
  17. EXT JS认识EXTJS,第一个EXTJS例子
  18. css基础教程
  19. pytorch怎么抽取中间的特征或者梯度
  20. Java命令学习系列(四)——jstat

热门文章

  1. .NET Core系列 :3 、使用多个项目
  2. Linux 江湖系列阶段性总结
  3. nodejs之get/post请求的几种方式
  4. 【原创经验分享】WCF之消息队列
  5. .NET中AOP方便之神SheepAspect
  6. 2016/12/31_Python
  7. SVN的使用
  8. SQL字符串函数
  9. Impress.js上手 - 抛开PPT、制作Web 3D幻灯片放映
  10. 解决开启服务器防火墙导致ftp不能连接的问题