数据点

Entity Framework 代码优先和 DbContext 常见问题解答

Julie Lerman

 

Julie Lerman
这个月,我想分享常见问题有关代码第一次和 DbContext 中的实体框架 4.2 的问题的答案。要最大限度的空间,我会指向额外资源,您可以在其中找到我所提供的材料的补充的详细的信息。

将代码第一次和 DbContext 将添加到。NET 框架?

号代码的第一次和 DbContext 将从 Microsoft 的分别进行分布。NET 框架释放周期,允许实体框架团队发布的更新,而无需等待下一次官方发布准备就绪。NET 框架。第一次代码,DbContext API EntityFramework.dll 程序集,您可以向您的项目使用 NuGet 动态添加的一部分。在 Visual Studio 中安装 NuGet 扩展名为您提供让您对 EntityFramework.dll 的引用添加到项目的库软件包管理器。图 1 显示的 EntityFramework 软件包 (目前 NuGet 包库中最受欢迎下载) 在 Visual Studio 库包管理器。

Installing Code First and DbContext into a Project via EntityFramework.dll
图 1 首先安装代码和入到项目中通过 EntityFramework.dll DbContext**

你可以阅读更多关于实体框架和为什么他们决定专注于使用 NuGet 部署某些类型的外部特征特性的发布团队的计划。在其 2011 年 10 月的博客,"如何我们谈论关于 EF 和及其未来版本"中网 Api (bit.ly/owoWgn)。

您可以筛选与包含相关的数据吗?

号包含方法允许您执行针对实体数据模型的查询时,热切地加载相关的数据。不幸的是,您可以检索渴望加载相关数据的唯一一个完整的集。这也是真正为延缓加载和所有,但一种情况,进行显式加载。该单个案例:当您显式加载通过更改跟踪器 API 时,您可以应用一种查询方法后, 跟一个 Where 筛选:

context.Entry(personInstance)
  .Collection(p => p.Aliases)
  .Query()
  .Where(a=>a.FirstName == "Natasha")
  .Load();

但很明显,你不能这样的渴望与包含加载。

这是包括一直以来的实体框架中的第一版。NET 框架 3.5。 如果要合并渴望加载筛选,考虑使用的预测。 你可以阅读更多关于这在 2011 年 6 月数据点列中,"Demystifying 实体框架战略:加载相关数据,"在 msdn.microsoft.com/magazine/hh205756。 我也在写博客上的话题,"使用预测和存储库到假过滤渴望负荷," bit.ly/uZdnxy

如何使用和一般包括与?

与 ObjectContext,包括使用的唯一方法是通过传入一个字符串来表示热切地加载的导航属性。 例如,如果您有一类的属性,树,这是 ICollection <Tree>,它的路你就会查询他们的树木,像这样的道路:

context.Roads.Include("Trees")

许多开发人员已创建他们自己的扩展方法,让他们转而使用强类型的表达式:

context.Roads.Include(r => r.Trees)

DbContext API 现在内置包括 lambda 表达式中使用的能力。 你会发现关于 DbContext API 的一部分 6 的亚瑟维氏的精彩 12 部分博客系列中的一个示例 (bit.ly/wgI5zW)。 您尝试使用此功能可能未获成功,但是 — — 如是我的。 我不得不放下我的自尊心,问某人在团队如何获得 lambda 支持。 事实证明在 EntityFramework.dll 的引用,您需要使用指令 (或进口的 Visual Basic) 为 System.Data.Entity,您试图使用包含带有 lambda 的代码文件中。 如果要扩展加载一个集合,使用和一般的关系的多个级别上的渴望,你要把额外的选择方法。 例如,如果您的类树有 ICollection <Leaf> 和你想要到渴望负荷随树的叶子,看起来像这样的字符串表示形式:

context.Roads.Include("Trees.Leaves")

但是,lambda 依赖额外的逻辑,以提供下一级别的关系。 这里是会选择道路与树木和它们的叶子一起使用的语法:

context.Roads.Include(r => r.Trees.Select(t => t.Leaves))

我不能说说使用的包含多个级别而不添加提醒人们,使用包含,更为复杂和降级可能成为您的 SQL 查询加载您尝试渴望更多的关系。 我总是强烈推荐性能分析生成的实体框架 (EF) 的 SQL。 事实上,2010 年 12 月的数据点列演示使用 EF 时,配置文件数据库的各种方式。

我很了解如果您使用的 ObjectContext API,EntityFramework.dll,加上使用指令的 System.Data.Entity 的引用将会让你使用和一般包括在这里,也吃惊。

我要等待。NET 框架 4.5,如果我想首先使用代码,WCF 数据服务?

为创建和使用 WCF 的数据服务中有两个程序集。NET 框架 4:System.Data.Services.dll 和 System.Data.Services.Client.dll。 如果您尝试使用这些与 DbContext 和代码第一类,他们不会工作框。 是 DbContext,不代码首先的问题。 DbContext 不存在时,这些程序集被修建,所以他们并不理解。 在 2011 年 3 月,微软发布了社区技术预览 (CTP) 包含知道如何使用 DbContext 的固定向上组件 (Microsoft.Data.Services.dll 和 Microsoft.Data.Services.Client.dll)。 所以你要做的一切是替换默认的程序集,这些新的程序集,并在您的数据服务,指定 DataServiceProtocolVersion V3,而不是 V2。 下面是一个简单的数据服务可能类似揭露继承自 DbContext 的上下文 (PersonModelContext) 的一个示例:

public class DataService : DataService<PersonModelContext>
  {
    public static void InitializeService(DataServiceConfiguration config)
    {
      config.SetEntitySetAccessRule("People", EntitySetRights.All);
      config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
    }
}

此解决方案的问题是新的程序集是只签注而不是为生产目的。 你将不得不等待到制造 (RTM) 版本的数据服务,以便能够在生产中使用它们的下一次发布。

但可以使用与 DbContext。NET 框架 4 System.Data.Services 的程序集。 CTP 程序集存在只是为了帮助你避免编写额外的代码。 您需要做的全部是访问底层的 ObjectContext,它支持 DbContext 和提供的服务。 2010 年 7 月,罗恩 · 米勒,一个重要的角色,在后面的代码第一次,微软表明这一篇博文中"EF CTP4 提示 & 技巧:在 DbContext 上的 WCF 数据服务"(bit.ly/c2EA0l)。 该博客是写早期预览的 DbContext,所以已经更新了他工作与 DbContext 类中使用 PersonModelContext,一个简单的模型公开一个 DbSet 人类的实体框架 4.2 版本的示例。 在图 2 中显示的上下文和类。

图 2 简单 DbContext 和数据服务所使用的类

public class PersonModelContext : DbContext
{
  public DbSet<Person> People { get; set; }
}
public class Person
{
  public int PersonId { get; set; }
  [MaxLength(10)]
  public string IdentityCardNumber { get; set; }
  public string FirstName { get; set; }
  [Required]
  public string LastName { get; set; }
}

然后定义数据服务工作与 ObjectContext,而不是专门为从 DbContext 派生的 PersonModelContext。 然后,通过重写数据服务 CreateData­源方法,您可以公开 ObjectContext 是 PersonModelContext,从而提供所需的 ObjectContext 的服务,如图 3 所示的基础。

图 3 A WCF 数据使用服务,与 DbContext。NET 框架 4 服务 Api

public class DataService : DataService<ObjectContext>
{
  public static void InitializeService(DataServiceConfiguration config)
  {
    config.SetEntitySetAccessRule("People", EntitySetRights.All);
    config.DataServiceBehavior.MaxProtocolVersion =
      DataServiceProtocolVersion.V2;
  }
  protected override ObjectContext CreateDataSource()
  {
    var dbContext = new PersonModelContext();
    var oContext = ((IObjectContextAdapter)dbContext).ObjectContext;
    return oContext;
  }
}

因为我想着重提供 ObjectContext,这是代码的您可能拥有 WCF 数据服务中的简化的视图。

这种方法的缺点是,您不能使用 DbContext 功能如验证 (我的 2011 年 12 月的数据点列"处理实体框架验证在 WCF 数据服务"中所述,在 msdn.microsoft.com/magazine/hh580732) 因为该服务的设计目的是与 ObjectContext 工作。

应该使用数据的注释或流利的 API 对于代码的第一个配置吗?

被问及这个问题很多。 要理解答案,最好先了解这两个选项之间的高级别差异。

代码首先扩展数据的注释,都已经部分。NET 框架 4 System.ComponentModel.DataAnnotations 命名空间。 除了,如 ValidationAttributes 的批注 (必填,StringLength,正则表达式),实体框架添加指定数据库映射 (例如,列、 表和时间戳) 或其他特定模型的功能,例如复杂类型的属性。 批注是简单地在类中,人的班,在图 2 中所示。

有一些可能的缺点,配置您的类的代码第一次使用数据的注释。 一个是你可能不会将与持久性相关的逻辑添加到您的业务类的风扇。 如果你问你自己,"不会数据库列的名称必须做什么与我的域模型?"你可能不想使用的数据的注释。 另一个是这些映射要求您以参考 EntityFramework.dll 从包含您的业务类的程序集。 (这而更改。NET 框架 4.5,将 EF 相关数据批注的所有权。)那,也可能不是你想做的尤其是如果你将应用程序分发跨层的东西。 此外,代码的第一个数据批注不要暴露配置,可以使用代码第一次应用的完整的阵容。 仅使用流利的 API,可以实现一些配置,例如那些指定的每个层次结构表 (TPH) 映射的特定详细信息。

我给开发商的建议是,选择你喜欢的样式。 如果您愿意让您实体框架 DbContext 所表示的配置,然后使用流利的 API。 如果您喜欢简单的应用属性并不介意有您的类中的代码第一个映射逻辑,使用的数据的注释。 如果您选择要使用的数据的注释和遇到过一种配置,可以表示只有流利的 API,然后流利地添加该配置和使用的数据的注释和流利的配置组合。

可以使用代码首先与现有数据库吗?

绝对 ! 虽然代码第一次的默认行为是 (有益) 为您创建一个数据库,但可以指向一个现有的数据库与您自己的连接字符串和有代码首次使用的。 有一些内部代码首,可让您以编程方式指定数据库和功能。 例如,您可以重载 DbContext 构造函数与数据库名称或数据库连接字符串。 你可以还指定和甚至自定义 DbContext ConnectionFactory 类型 (例如,SqlConnectionFactory)。

您需要确保代码第一公约加上准确地添加任何配置代表您的类将映射到现有数据库的方式。 微软已经在一种工具,可以将数据库进行反向工程到类加代码第一口流利的配置,可以提供很好的头开始。 您可以了解有关此工具在我的 2011 年 5 月的博客帖子,"快速看在逆向工程师 DB 到代码第一类"(bit.ly/lHJ2Or)。

当指定的位置,避免架构验证和 DbContext 不会默认情况下,与代码第一次的数据库初始化。 您可以完全禁用此功能,通过代码第一次数据库初始化:

Database.SetInitializer<MyContext>(null)

你会找到更多关于这一主题在 MSDN 数据开发人员中心文章和视频,"数据库初始值设定项实体框架 4.1"(msdn.microsoft.com/data/hh272552)。 有关使用 ConnectionFactory 类和 DbContext 重载的详细示例,请确保检查"编程实体框架:代码第一次"(O'Reilly 介质,2011年),我从代码第一团队合著罗恩 · 米勒的一本书。

其他资源

有很多地方,了解有关使用代码第一次和 DbContext。 在实体框架团队博客 blogs.msdn.com/adonet 充满突飞猛进和例子。 有些团队成员的博客,例如罗恩 · 米勒 (romiller.com) 和亚瑟维氏的 (blog.oneunicorn.com/author/ajcvickers),阅读有关的伟大的地方高级技术。 MSDN 论坛和 StackOverflow.com 继续读取线程或您自己问的好地方。 米勒和我最近写了两个短书,上述"编程实体框架:代码第一"和"编程实体框架:DbContext"(O'Reilly 介质,2012年)。 你可以得到这些打印或数字格式。

有无需苦苦挣扎试图找出关于你自己的事情。

Julie Lerman 是 Microsoft MVP。净的导师和顾问住在佛蒙特州的丘陵。您可以查找数据访问和其它微软对她提出。用户组和世界各地的会议的净主题。在她的博客 thedatafarm.com/blog 和"编程实体框架"的作者是 (2010 年) 和"编程实体框架:代码第一次"(2011 年),两者都从 O'Reilly 媒体。跟着她在 Twitter 上 twitter.com/julielerman

多亏了以下的技术专家审查这篇文章:Mike FlaskoDiego Vega