本文介绍了DbContext多重继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The design of EF forces developers to inherit the DbContext class. Some reusable libraries (such as ASP.NET Identity) typically provides its functionality using the same inheritance route, i.e. by providing the IdentityDbContext base-class.

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

But obviously this won't work if you have 2 such libraries, e.g. requiring you to inherit from IdentityDbContext and CmsDbContext at the same time, which is obviously impossible to do on .NET. The result that I want is to have an application-dbcontext that contains both the models from my identity module and my cms module (I won't be able to separate this to 2 dbcontexts since that would mean I will end up with multiple connections and transactions, and that my models can only reference to either identity or cms entities, but not both).

很难相信这个问题似乎并未在EF社区中被问到,但这似乎是一个非常糟糕的ORM设计.继承只允许您进行严格的线性模块化.(作为比较,在NHibernate中,ISession和您的Configuration是两个独立的事物,因此您可以使用发现过程从不同的不相关模块中构建映射配置,而不会弄乱我的ISession以及我的db-connection/transactions).

It's hard to believe that this question hasn't seemed to be asked around EF community, but this seems like a horrendously bad ORM design. Inheritance only lets you to have strictly linear modularisation. (As a comparison, in NHibernate, ISession and your Configuration are 2 separate things, therefore you can use discovery process to build up your mapping-configuration from different unrelated modules, without messing with my ISession and thus my db-connection/transactions).

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

So the question is, let's say you're a developer of a module that would like to register models into entity-framework (similar to ASP.NET identity module), you won't want to have a base DbContext that the consuming application must inherit, because it would prevent them from consuming other modules (e.g. ASP.NET identity's IdentityDbContext). So what are my options?Is there any way to register models into a DbContext class without requiring to inherit from a DbContext? Is overriding OnModelCreating the only way to get access to a ModelBuilder?

推荐答案

我认为您的比较不完全公平.(尽管我是第一个承认NHibernate在许多方面都胜过EF的人.)

I don't think your comparison is entirely fair. (Although I'm the first to admit that NHibernate beats EF in many areas).

对于NHibernate,通常使用某种通用方法来加载对象,在其中提供要加载的类型.您可以使用硬编码的 Query< T> (或 QueryOver< T> )属性创建 ISession 实现,喜欢...

With NHibernate, usually you load objects by some generic method in which you supply the type you want to load. You could create ISession implementations with hard-coded Query<T> (or QueryOver<T>) properties, like...

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

...您将遇到一个无法合并或继承两个不同实现的相同问题".

...and you'd have the same "problem" that you can't merge, or inherit from, two different implementations.

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

Likewise, you could work with EF by loading objects by using context.Set<T> only. You could even inject the configuration (sort of) by supplying EntityTypeConfiguration classes (as a list) in the context's constructor, storing them in a member variable and adding them to the model builder in the OnModelCreating override.

这些专门的上下文类(如 IdentityDbContext )可以使您更轻松地生活.它们具有硬编码的 DbSet 属性(以及其他属性).您不能多重继承它们的事实并不是设计缺陷.这只是(不可商议的)语言规范.

These specialized context classes, like IdentityDbContext, are offered to make life easier if they suit you. They have hard-coded DbSet properties (among others). The fact that you can't multiple inherit them is not a design flaw. It's just a (non-negotiable) language specification.

选择最能满足您需求的代码(最好是 CmsDbContext ),然后自己添加其他类映射.

Choose the one that most closely serves your needs (propably CmsDbContext) and add other class mappings yourself.

这篇关于DbContext多重继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-01 19:19