Entity Framework: One Database, Multiple DbContext

2018-12-31 18:52发布

My impression to date has been that a DbContext is meant to represent your database, and thus, if your application uses one database, you'd want only one DbContext. However, some colleagues want to break functional areas out into separate DbContext classes. I believe this comes from a good place -- a desire to keep the code cleaner -- but it seems volatile. My gut's telling me it's a bad idea, but unfortunately my gut feeling is not a sufficient condition for a design decision.

So I'm looking for A) concrete examples of why this might be a bad idea, or B) assurances that this'll all work out just fine.

11条回答
何处买醉
2楼-- · 2018-12-31 19:22

I want to share a case, where I think the possibility of having multiple DBContexts in the same database makes good sense.

I have a solution with two database. One is for domain data except user information. The other is solely for user information. This division is primarily driven by the EU General Data Protection Regulation. By having two databases, I can freely move the domain data around (e.g. from Azure to my development environment) as long as the user data stays in one secure place.

Now for the user database I have implemented two schemas through EF. One is the default one provided by the AspNet Identity framework. The other is our own implementing anything else user related. I prefer this solution over extending the ApsNet schema, because I can easily handle future changes to AspNet Identity and at the same time the separation makes it clear to the programmers, that "our own user information" goes in the specific user schema we have defined.

查看更多
弹指情弦暗扣
3楼-- · 2018-12-31 19:28

Simple example to achieve the below:

    ApplicationDbContext forumDB = new ApplicationDbContext();
    MonitorDbContext monitor = new MonitorDbContext();

Just scope the properties in the main context: (used to create and maintain the DB) Note: Just use protected: (Entity is not exposed here)

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("QAForum", throwIfV1Schema: false)
    {

    }
    protected DbSet<Diagnostic> Diagnostics { get; set; }
    public DbSet<Forum> Forums { get; set; }
    public DbSet<Post> Posts { get; set; }
    public DbSet<Thread> Threads { get; set; }
    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
    }
}

MonitorContext: Expose separate Entity here

public class MonitorDbContext: DbContext
{
    public MonitorDbContext()
        : base("QAForum")
    {

    }
    public DbSet<Diagnostic> Diagnostics { get; set; }
    // add more here
}

Diagnostics Model:

public class Diagnostic
{
    [Key]
    public Guid DiagnosticID { get; set; }
    public string ApplicationName { get; set; }
    public DateTime DiagnosticTime { get; set; }
    public string Data { get; set; }
}

If you like you could mark all entities as protected inside the main ApplicationDbContext, then create additional contexts as needed for each separation of schemas.

They all use the same connection string, however they use separate connections, so do not cross transactions and be aware of locking issues. Generally your designing separation so this shouldn't happen anyway.

查看更多
伤终究还是伤i
4楼-- · 2018-12-31 19:31

This thread just bubbled up on StackOverflow and so I wanted to offer another "B) assurance that this will all be fine" :)

I'm doing exactly this by way of the DDD Bounded Context pattern. I've written about it in my book, Programming Entity Framework: DbContext and it is the focus of a 50 minute module within one of my courses on Pluralsight -> http://pluralsight.com/training/Courses/TableOfContents/efarchitecture

查看更多
旧时光的记忆
5楼-- · 2018-12-31 19:32

You can have multiple contexts for single database. It can be useful for example if your database contains multiple database schemas and you want to handle each of them as separate self contained area.

The problem is when you want to use code first to create your database - only single context in your application can do that. The trick for this is usually one additional context containing all your entities which is used only for database creation. Your real application contexts containing only subsets of your entities must have database initializer set to null.

There are other issues you will see when using multiple context types - for example shared entity types and their passing from one context to another, etc. Generally it is possible, it can make your design much cleaner and separate different functional areas but it has its costs in additional complexity.

查看更多
伤终究还是伤i
6楼-- · 2018-12-31 19:34

Another bit of "wisdom". I have a database facing both, the internet and an internal app. I have a context for each face. That helps me to keep a disciplined, secured segregation.

查看更多
登录 后发表回答