与模型相比,我应该拥有多少个DbContext子类?

时间:2022-10-05 14:11:46

I'm learning ASP.NET MVC and I'm having some questions that the tutorials I've read until now haven't explored in a way that covers me. I've tried searching, but I didn't see any questions asking this. Still, please forgive me if I have missed an existing ones.

我正在学习ASP.NET MVC,而且我有一些问题,我到目前为止所阅读的教程还没有以涵盖我的方式进行探索。我试过搜索,但我没有看到任何问题。如果我错过了现有的,请原谅我。

If I have a single ASP.NET MVC application that has a number of models (some of which related and some unrelated with each other), how many DbContext subclasses should I create, if I want to use one connection string and one database globally for my application?

如果我有一个具有多个模型的ASP.NET MVC应用程序(其中一些相关且一些相互关联),我应该创建多少个DbContext子类,如果我想全局使用一个连接字符串和一个数据库我的应用程序?

  • One context for every model?
  • 每种型号都有一个背景?

  • One context for every group of related models?
  • 每组相关模型的一个背景?

  • One context for all the models?
  • 所有模型的一个背景?

If the answer is one of the first two, then is there anything I should have in mind to make sure that only one database is created for the whole application? I ask because, when debugging locally in Visual Studio, it looks to me like it's creating as many databases as there are contexts. That's why I find myself using the third option, but I'd like to know if it's a correct practice or if I'm making some kind of mistake that will come back and bite me later.

如果答案是前两个中的一个,那么我是否应该考虑确保只为整个应用程序创建一个数据库?我问,因为在Visual Studio中进行本地调试时,我认为它创建了与上下文一样多的数据库。这就是为什么我发现自己使用第三种选择,但我想知道这是否是一种正确的做法,或者我是否会犯某种错误,以后再回来咬我。

3 个解决方案

#1


4  

@jrummell is only partially correct. Entity Framework will create one database per DbContext type, if you leave it to its own devices. Using the concept of "bounded contexts" that @NeilThompson mentioned from Julie Lerhman, all you're doing is essentially telling each context to actually use the same database. Julie's method uses a generic pattern so that each DbContext that implements it ends up on the same database, but you could do it manually for each one, which would look like:

@jrummell只是部分正确。如果将其留给自己的设备,Entity Framework将为每个DbContext类型创建一个数据库。使用@NeilThompson从Julie Lerhman提到的“有界上下文”的概念,你所做的只是告诉每个上下文实际使用相同的数据库。 Julie的方法使用通用模式,因此实现它的每个DbContext最终都在同一个数据库上,但你可以手动为每个实现它,如下所示:

public class MyContext : DbContext
{
    public MyContext()
        : base("name=DatabaseConnectionStringNameHere")
    {
        Database.SetInitializer(null);
    }
}

In other words, Julie's method just sets up a base class that each of your contexts can inherit from that handles this piece automatically.

换句话说,Julie的方法只是设置一个基类,每个上下文都可以从中继承自动处理这个部分。

This does two things: 1) it tells your context to use a specific database (i.e., the same as every other context) and 2) it tells your context to disable database initialization. This last part is important because these contexts are now essentially treated as database-first. In other words, you now have no context that can actually cause a database to be created, or to signal that a migration needs to occur. As a result, you actually need another "master" context that will have every single entity in your application in it. You don't have to use this context for anything other than creating migrations and updating your database, though. For your code, you can use your more specialized contexts.

这样做有两件事:1)它告诉你的上下文使用特定的数据库(即,与其他每个上下文相同)和2)它告诉你的上下文禁用数据库初始化。最后一部分很重要,因为这些上下文现在基本上被视为数据库优先。换句话说,您现在没有可以实际创建数据库的上下文,或者表示需要进行迁移的信号。因此,您实际上需要另一个“主”上下文,其中包含应用程序中的每个实体。但是,除了创建迁移和更新数据库之外,您不必将此上下文用于其他任何操作。对于您的代码,您可以使用更专业的上下文。

The other thing to keep in mind with specialized contexts is that each instantiation of each context represents a unique state even if they share entities. For example, a Cat entity from one context is not the same thing as a Cat entity from a second context, even if they share the same primary key. You will get an error if you retrieved the Cat from the first context, updated it, and then tried save it via the second context. That example is a bit contrived since you're not likely to have the same entity explicitly in two different contexts, but when you get into foreign key relationships and such it's far more common to run into this problem. Even if you don't explicitly declare a DbSet for a related entity, it an entity in the context depends on it, EF will implicitly create a DbSet for it. All this is to say that if you use specialized contexts, you need to ensure that they are truly specialized and that there is zero crossover at any level of related items.

要考虑专门的上下文,另一件事是每个上下文的每个实例化都代表一个独特的状态,即使它们共享实体也是如此。例如,来自一个上下文的Cat实体与来自第二个上下文的Cat实体不同,即使它们共享相同的主键。如果从第一个上下文中检索Cat,更新它,然后尝试通过第二个上下文保存它,则会出现错误。这个例子有点人为,因为你不可能在两个不同的上下文中明确地拥有相同的实体,但是当你进入外键关系时,遇到这个问题就更常见了。即使您没有为相关实体显式声明DbSet,它在上下文中的实体依赖于它,EF将隐式为它创建一个DbSet。所有这一切都是说,如果你使用专门的上下文,你需要确保它们真正专业化,并且在任何级别的相关项目上都没有交叉。

#2


5  

I use what Julie Lerman calls the Bounded Context

我使用Julie Lerman所谓的有界上下文

The SystemUsers code might have nothing to do with Products - so I might have a System DbContext and a Shop DbContext (for example).

SystemUsers代码可能与产品无关 - 所以我可能有一个System DbContext和一个Shop DbContext(例如)。

Life is easier with a single context in a small app, but for larger application it helps to break the contexts up.

在小应用程序中使用单个上下文可以更轻松地生活,但对于更大的应用程序,它有助于打破上下文。

#3


0  

Typically, you should have one DbContext per database. But if you have separate, unrelated groups of models, it would make sense to have separate DbContext implementations.

通常,每个数据库应该有一个DbContext。但是如果你有单独的,不相关的模型组,那么拥有单独的DbContext实现是有意义的。

it looks to me like it's creating as many databases as there are contexts.

它看起来像是在创建与上下文一样多的数据库。

That's correct, Entity Framework will create one database per DbContext type.

这是正确的,Entity Framework将为每个DbContext类型创建一个数据库。

#1


4  

@jrummell is only partially correct. Entity Framework will create one database per DbContext type, if you leave it to its own devices. Using the concept of "bounded contexts" that @NeilThompson mentioned from Julie Lerhman, all you're doing is essentially telling each context to actually use the same database. Julie's method uses a generic pattern so that each DbContext that implements it ends up on the same database, but you could do it manually for each one, which would look like:

@jrummell只是部分正确。如果将其留给自己的设备,Entity Framework将为每个DbContext类型创建一个数据库。使用@NeilThompson从Julie Lerhman提到的“有界上下文”的概念,你所做的只是告诉每个上下文实际使用相同的数据库。 Julie的方法使用通用模式,因此实现它的每个DbContext最终都在同一个数据库上,但你可以手动为每个实现它,如下所示:

public class MyContext : DbContext
{
    public MyContext()
        : base("name=DatabaseConnectionStringNameHere")
    {
        Database.SetInitializer(null);
    }
}

In other words, Julie's method just sets up a base class that each of your contexts can inherit from that handles this piece automatically.

换句话说,Julie的方法只是设置一个基类,每个上下文都可以从中继承自动处理这个部分。

This does two things: 1) it tells your context to use a specific database (i.e., the same as every other context) and 2) it tells your context to disable database initialization. This last part is important because these contexts are now essentially treated as database-first. In other words, you now have no context that can actually cause a database to be created, or to signal that a migration needs to occur. As a result, you actually need another "master" context that will have every single entity in your application in it. You don't have to use this context for anything other than creating migrations and updating your database, though. For your code, you can use your more specialized contexts.

这样做有两件事:1)它告诉你的上下文使用特定的数据库(即,与其他每个上下文相同)和2)它告诉你的上下文禁用数据库初始化。最后一部分很重要,因为这些上下文现在基本上被视为数据库优先。换句话说,您现在没有可以实际创建数据库的上下文,或者表示需要进行迁移的信号。因此,您实际上需要另一个“主”上下文,其中包含应用程序中的每个实体。但是,除了创建迁移和更新数据库之外,您不必将此上下文用于其他任何操作。对于您的代码,您可以使用更专业的上下文。

The other thing to keep in mind with specialized contexts is that each instantiation of each context represents a unique state even if they share entities. For example, a Cat entity from one context is not the same thing as a Cat entity from a second context, even if they share the same primary key. You will get an error if you retrieved the Cat from the first context, updated it, and then tried save it via the second context. That example is a bit contrived since you're not likely to have the same entity explicitly in two different contexts, but when you get into foreign key relationships and such it's far more common to run into this problem. Even if you don't explicitly declare a DbSet for a related entity, it an entity in the context depends on it, EF will implicitly create a DbSet for it. All this is to say that if you use specialized contexts, you need to ensure that they are truly specialized and that there is zero crossover at any level of related items.

要考虑专门的上下文,另一件事是每个上下文的每个实例化都代表一个独特的状态,即使它们共享实体也是如此。例如,来自一个上下文的Cat实体与来自第二个上下文的Cat实体不同,即使它们共享相同的主键。如果从第一个上下文中检索Cat,更新它,然后尝试通过第二个上下文保存它,则会出现错误。这个例子有点人为,因为你不可能在两个不同的上下文中明确地拥有相同的实体,但是当你进入外键关系时,遇到这个问题就更常见了。即使您没有为相关实体显式声明DbSet,它在上下文中的实体依赖于它,EF将隐式为它创建一个DbSet。所有这一切都是说,如果你使用专门的上下文,你需要确保它们真正专业化,并且在任何级别的相关项目上都没有交叉。

#2


5  

I use what Julie Lerman calls the Bounded Context

我使用Julie Lerman所谓的有界上下文

The SystemUsers code might have nothing to do with Products - so I might have a System DbContext and a Shop DbContext (for example).

SystemUsers代码可能与产品无关 - 所以我可能有一个System DbContext和一个Shop DbContext(例如)。

Life is easier with a single context in a small app, but for larger application it helps to break the contexts up.

在小应用程序中使用单个上下文可以更轻松地生活,但对于更大的应用程序,它有助于打破上下文。

#3


0  

Typically, you should have one DbContext per database. But if you have separate, unrelated groups of models, it would make sense to have separate DbContext implementations.

通常,每个数据库应该有一个DbContext。但是如果你有单独的,不相关的模型组,那么拥有单独的DbContext实现是有意义的。

it looks to me like it's creating as many databases as there are contexts.

它看起来像是在创建与上下文一样多的数据库。

That's correct, Entity Framework will create one database per DbContext type.

这是正确的,Entity Framework将为每个DbContext类型创建一个数据库。