问题
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.
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).
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).
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?
回答1:
I don't think your comparison is entirely fair. (Although I'm the first to admit that NHibernate beats EF in many areas).
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.
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.
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.
Choose the one that most closely serves your needs (propably CmsDbContext) and add other class mappings yourself.
来源:https://stackoverflow.com/questions/28737686/dbcontext-multiple-inheritance