【问题标题】:DbContext Multiple InheritanceDbContext 多重继承
【发布时间】:2015-02-26 08:34:35
【问题描述】:

EF 的设计迫使开发者继承 DbContext 类。一些可重用的库(例如 ASP.NET Identity)通常使用相同的继承路径提供其功能,即通过提供 IdentityDbContext 基类。

但是如果你有 2 个这样的库,这显然是行不通的,例如要求您同时从 IdentityDbContext 和 CmsDbContext 继承,这在 .NET 上显然是不可能的。我想要的结果是有一个 application-dbcontext 包含来自我的身份模块和我的 cms 模块的模型(我将无法将其分离为 2 个 dbcontexts,因为这意味着我最终将获得多个连接和交易,并且我的模型只能引用身份或 cms 实体,但不能同时引用两者)。

很难相信这个问题似乎没有在 EF 社区中被问到,但这似乎是一个非常糟糕的 ORM 设计。继承只允许您进行严格的线性模块化。 (作为比较,在 NHibernate 中,ISession 和您的配置是 2 个独立的东西,因此您可以使用发现过程从不同的不相关模块构建映射配置,而不会弄乱我的 ISession 以及我的数据库连接/事务)。

所以问题是,假设您是一个模块的开发人员,想要将模型注册到实体框架(类似于 ASP.NET 标识模块)中,您不希望有一个基础 DbContext使用应用程序必须继承,因为它会阻止它们使用其他模块(例如 ASP.NET 身份的 IdentityDbContext)。那么我的选择是什么? 有什么方法可以将模型注册到 DbContext 类中而不需要从 DbContext 继承?覆盖 OnModelCreating 是访问 ModelBuilder 的唯一方法吗?

【问题讨论】:

    标签: entity-framework


    【解决方案1】:

    我认为你的比较并不完全公平。 (虽然我是第一个承认 NHibernate 在很多方面都胜过 EF 的人)。

    使用 NHibernate,通常您通过一些通用方法加载对象,在这些方法中您提供要加载的类型。您可以使用硬编码的Query<T>(或QueryOver<T>)属性创建ISession 实现,例如...

    public Query<MyUser> Users { get; set; }
    

    ...您会遇到无法合并或继承两个不同实现的相同“问题”。

    同样,您可以通过仅使用 context.Set&lt;T&gt; 加载对象来使用 EF。您甚至可以通过在上下文的构造函数中提供EntityTypeConfiguration 类(作为列表)来注入配置(某种程度上),将它们存储在成员变量中并将它们添加到OnModelCreating 覆盖中的模型构建器中。

    这些专门的上下文类,如IdentityDbContext,如果适合您,可以让生活更轻松。他们有硬编码的DbSet 属性(等等)。您不能多重继承它们的事实不是设计缺陷。这只是一个(不可协商的)语言规范。

    选择最能满足您需求的一个(可能是CmsDbContext)并自己添加其他类映射。

    【讨论】:

    • 我不是这个意思。我不在乎在我的 DbContext 上有一个属性。其实我更喜欢dbcontext.Set,所以那里没有问题。我的问题只是首先将实体类型注册到 dbcontext。我知道如何在 EF 中这样做的唯一方法是通过 ModelBuilder,访问模型构建器的唯一方法是覆盖 DbContext 类上的 OnModelCreating 方法。这意味着如果您想重用来自 ASP.NET 身份的注册是通过继承提供的 IdentityDbContext 基类(其中包含 OnModelCreating 实现)...
    • ... 但假设这是我想要使用的唯一组件。现在,如果我有多个这样的基本 DbContext,我该怎么办?在 nhibernate 中,您可以拥有任意数量的独立组件,每个组件都有自己的一组实体映射(通过嵌入式 hbm 或流式映射)。我无法弄清楚如何在 EF 中这样做。所有示例仅讨论从 1 个组件(通常是 IdentityDbContext)继承。没有人谈论任何第二个组件
    • Btw IdentityDbContext 不是为了让您的生活更轻松而提供的。这是您必须 让模块正常工作的东西。它不仅仅是 DbSet 属性的包装器,我不在乎。它包含 OnModelCreating 和 ValidateEntity 方法的实现,这是它工作所需的配置(实体注册、属性映射、实体关系和验证规则)
    • 嗯,它不会改变您使用这些类的方式。选择其中之一。就是这样。顺便说一句,我不同意你的看法。我认为在 EF 中具有可注入配置或实现自动发现是一个好主意(并且可行)。我只使用 EF,因为它的 LINQ 实现要好得多,但有时看到所有这些 NHibernate 功能会很诱人......
    • 你能澄清一下你选择其中一个是什么意思吗?你的意思是我只能选择 1 个使用 EF 的单一库? IE。要么我选择使用 ASP.NET 标识、CMS 引擎、产品目录引擎或 ShoppingCart 引擎,但在同一个应用程序中没有两个(或更多)?当然,确实改变了我使用这些类的方式:我不能使用它们。
    猜你喜欢
    • 2011-07-15
    • 2020-10-13
    • 2010-09-27
    • 2012-03-07
    • 2012-06-02
    • 2017-03-31
    • 1970-01-01
    相关资源
    最近更新 更多