数据点

揭开 Entity Framework 策略的面纱,第 3 部分:类、查询和上下文

朱莉列尔曼

Julie Lerman
这是一系列旨在帮助您作出一些重要的决定,为您在应用程序中的数据访问层使用实体框架时的数据点列第三。第一,关于在 2011 年 5 月问题模型创建工作流 (bit.ly/lOcjPz)、 讨论选择之间的代码第一、 模型第一次和数据库第一次的工作流。代码首先不使用可视化的模型,但数据库第一次和模型第一次做。当你有,您将创建您的域类的视觉模型,一个在此列中的目标选择将重点的代码生成选项。在代码生成的主题,我要看看使用 ObjectContext 和 DbContext 和 LINQ to 实体和实体 SQL 之间选择之间进行选择。

生成的类: EntityObjects 或波苏斯吗?

实体框架 (以下简称为简洁起见 EF) 的第一个版本依靠 EntityObject 类,使与 ObjectContext 进行交互,因为它管理关系和跟踪的更改为实体实例的实体。代码生成确保从您的模型生成的类继承 EntityObject。这仍然是默认用 Visual Studio 2010,但现在您有另一个选项。在 Microsoft。NET 框架 4、 EF 和其 ObjectContext 获得能够跟踪更改和管理不取决于将通知发送给 ObjectContext EntityObject 实体之间的关系。这意味着您的类不再有继承 EntityObject,这使得开发人员感兴趣的持久性无知、 关注、 单元测试和其他软件做法属于敏捷开发的广义伞分离一个巨大的差异。

不依赖于其它 Api 的类称为平原老 CLR 对象或波苏斯。使用这些清洁类,但仍执行其更改跟踪和其他实体管理任务的 EF 能力称为"POCO 支持"。这种支持的代码第一次主干。因为 EF 是能够与 POCO 实体的工作,也可以由 EF 上下文管理在代码第一次的情况下创建的类。

所以如果 EF 依赖于通知更改实体的上下文的 EntityObject,如何是它可能有波苏斯,不但不继承 EntityObject,有没有知识的 EF?EF 使用两条路径,让开发人员有他们谚语的蛋糕和也吃。不会更改的一件事是 ObjectContext 还需要了解哪些类是负责。

ObjectContext 获取更明智的选择,结果 POCO 支持的第一个路径。NET 框架 4。现在的上下文是能够检查它管理的类。它具有新的方法,如 DetectChanges,将读取它管理的对象,然后更新它跟踪这些对象的状态信息。

时仍然能够受益框架使用的代理对象形式的戏法位 EF 让第二种方法使用波苏斯。如果每一个 POCO 类属性被标记为虚拟,EF 运行时将创建对象周围的代理服务器 (包装) 和该代理是否与 EntityObject 相同的职业。代理类将通知上下文的属性和关系的变化。您还可以利用代理服务器而不会影响整个类。EF 将能够延缓加载导航属性标记为虚拟的即使其他属性不是。

图 1显示为以实体的变化,使用 EntityObjects 或两个的 POCO 机制之一 ObjectContext 现在可用的三种方式的可视化表示形式。

How Entity Framework Tracks Changes to Entities

图 1实体框架轨道如何更改为实体

ObjectContext 或 DbContext?

EF 4.1 推出名为 DbContext 的 ObjectContext 的轻量的版。它提供了所有与 ObjectContext 相同的 POCO 支持。DbContext 还换一些更复杂的逻辑,所需的编码对 ObjectContext 到更简单的方法和属性,使得在 EF 中执行的最常见的编码任务变得更加容易。

DbContext 是用于代码第一类的默认上下文,但 ObjectContext 是默认数据库第一次与模型第一。Microsoft 提供备用的代码生成模板为后者的两种模式。第一个是 ADO。波苏净实体发电机。这将创建 POCO 类随 ObjectContext 类来管理它们。第二,EF 4.1 安装的一部分是 ADO。NET DbContext 发电机。这还会创建 POCO 类。但从 DbContext 到管理类生成的上下文类继承。所以无论工作流你开始与 — — 代码第一、 模型首或数据库第一 — — 您已使用 DbContext,如果这是您的首选项选项。DbContext 有一个窗口到 ObjectContext,这样您就可以获得那里如果需要。

查询选项:LINQ to Entities 或实体 SQL

开发人员有关于 EF 的另一个大问题是如果他们应使用 LINQ to 实体或实体 SQL 编写和执行查询。他们还要求两个存在的理由。实体 SQL 是与实体数据模型中建其本机查询语法来决定的。LINQ 是 C# 和 Visual Basic 的扩展和创建语言队。当数据平台组获悉有关 LINQ 上所做的工作时,他们知道它会 EF 的查询需要的自然延伸,所以他们创建 LINQ to 实体实施。

LINQ to 实体作为您的默认查询策略

LINQ to 实体是 LINQ to 对象的实现。LINQ 使您可以编写查询针对强类型对象,并在的情况下 EF,您可以编写查询对实体类。LINQ 被表示两种方式。第一个是与营办商。查询语句的样子有点像 SQL 语句。查询需要 EntityContainer,ObjectContext,这里称为上下文继承的实例:

IQueryable<Family> query =
  from f in context.Families where f.Pets.Any() select f;

当您键入此表达式,智能感知可帮助您不只是强类型的类,但也使用 LINQ 的语法。 该查询会返回 IQueryable 的家庭类型。 查询仍需要,例如 ToList 的执行:

List<Family> reptileFamilies = query.ToList();

这将导致 EF 在数据库上执行查询,抓住从数据库结果和创建使用这些结果的对象。

LINQ 查询表示第二种方法是使用 LINQ 方法。 这些都需要 lambda 表达式作为其参数。 我会压缩到一个 LINQ 查询中的两个前面的发言:

List<Family> reptileFamiles = 
  context.Families.Where(f=>f.Pets.Any()).ToList();

因为 LINQ 是如此简单易用,快递查询 — 多亏了强类型和智能感知 — — 我一般建议开发人员计划使用 LINQ 作为其默认查询策略。 你可以表达各种各样的 LINQ 查询。 此外,由于 LINQ 有许多实现,可能就已经好句柄上使用它。 如果没有,您很可能将受益于学习 LINQ to 实体和解决其他编码问题使用 LINQ to 对象或其他很多口味 LINQ 之一。 另外,您可以找到很好的很多资源学习如何使用 LINQ 查询。

实体 SQL 的边缘案例查询和其他语言

实体 SQL 是一种基于字符串的查询语法。 要执行使用实体 SQL 查询,您需要使用 EF ObjectQuery 和实体 SQL 表达式中传递。 这看起来像什么? 下面是一个示例:

string eSql = "SELECT VALUE f FROM PetsModelContainer.Families AS f";
ObjectQuery<Family> query = context.CreateQuery<Family>(eSql);
List<Family> families = query.ToList();

像你创建 LINQ 的 IQueryable,此 ObjectQuery 仍需要执行以从数据库中检索结果。 ObjectQuery 不会提供另一种使用方法,以作为其参数的实体 SQL 代码段创建查询的方式。

但与字符串表达式中,有没有强类型和查询表达式不能得到解决,直到运行时,这意味着您不会在此之前发现问题。 (请注意您可以使用不可或缺的 LINQPad — — 发现在linqpad.net— — 测试实体 SQL 以及 LINQ to 实体,外面的 Visual Studio。)那么为什么会有人想使用实体 SQL?

有很多原因。

让我们开始用您的代码中的语言。 LINQ 是 C# 和 Visual Basic 的一部分。 有 F # LINQ 提供的电源包。 如果您在任何其他代码。网络语言,您不能使用 LINQ。 但是,您仍可以使用实体 SQL 来表示查询。 我还发现实体 SQL 有用构建复杂搜索实用程序在应用程序中。 LINQ 是可组合,但在某一时刻,就只是很容易,只需建立一个字符串。

您还可以在连接和命令与实体 SQL 表达式一起使用的 EF 执行较低级别的查询。 此路径返回流的数据,是伟大的报告或移动数据。

查询、 代码生成和上下文选项

虽然建议使用 LINQ to 实体作为您的默认查询策略,你见过为什么您可能要在边缘情况下利用实体 SQL 的原因。 这是我做什么,我推荐给客户端,和我总是快乐的行使我不经常使用的实体 SQL 排骨的借口。 在 MSDN 上的文档是非常全面的学习如何生成实体 SQL 表达式。 但除此之外,一些老的博客文章从外汇基金团队和我的书,"编程实体框架"(O'Reilly 媒体,2010年),我不知道许多资源学习语法中的一章。

代码生成上,使用 EntityObjects 如果您正在编写简单应用程序,并且希望只是工作的事情是一个好的策略。 但是,如果您正在构建要有持续性无知类应用程序,使用单元测试并按照分离关注点,那就是 EF 波苏支持成立的路径。 即使这样,你有一些使用纯对象将需要一点额外注意编码或利用代理的生成会让 EF 做小干扰其工作时的灵活性。

EF 4.1 将多一项选择添加到代码生成,这 ObjectContext 或 DbContext 管理您 POCO 类之间进行选择。 许多开发人员跳转到 DbContext,因为它是简单的 API 来处理。 如果您需要更精细的级别的交互更改跟踪,控制或愿意利用现有的代码或知识的 ObjectContext,您可以继续使用 ObjectContext 作为基地为您的上下文。

朱莉列尔曼 是 Microsoft MVP。净的导师和顾问住在山上的佛蒙特。您可以找到她提出对数据的访问和其他 Microsoft。用户组和世界各地的会议的净主题。在她的博客thedatafarm.com/blog是备受推崇的书,"编程实体框架"(O'Reilly 媒体,2010年) 的作者。请关注她的 Twitter:twitter.com/julielerman

衷心感谢以下技术专家对本文的审阅:蒂姆 · 莱弗蒂