到目前为止,我的印象是DbContext
用于表示您的数据库,因此,如果您的应用程序使用一个数据库,您只需要一个DbContext
。
然而,一些同事想将功能区域拆分成单独的DbContext
类。
我认为这源于善意——希望保持代码更加清晰——但它似乎不稳定。我的直觉告诉我这是个坏主意,但不幸的是,我的直觉并不足以成为设计决策的充分条件。
所以我正在寻找:
A)具体例子说明这可能是个坏主意;
B)保证这将会很好地解决问题。
到目前为止,我的印象是DbContext
用于表示您的数据库,因此,如果您的应用程序使用一个数据库,您只需要一个DbContext
。
然而,一些同事想将功能区域拆分成单独的DbContext
类。
我认为这源于善意——希望保持代码更加清晰——但它似乎不稳定。我的直觉告诉我这是个坏主意,但不幸的是,我的直觉并不足以成为设计决策的充分条件。
所以我正在寻找:
A)具体例子说明这可能是个坏主意;
B)保证这将会很好地解决问题。
哎呀,花了很多时间解决每个数据库模式的单独DB上下文问题,希望这能帮助到其他人...
最近我开始处理一个项目,该项目有一个包含3个模式的数据库(采用DB first方法),其中一个模式用于用户管理。每个单独模式都有一个DB上下文脚手架。当然,用户也与其他模式相关联,例如,模式KB有一个名为Topic的表,其中包括“创建者”、“最后修改者”等信息。外键指向identity模式,表appuser。
这些对象在C#中分别加载,首先从1个上下文中加载主题,然后通过用户ID从另一个db上下文中加载用户 - 不好,必须修复! (类似于使用EF 6在同一数据库中使用多个dbcontexts)
首先,我尝试将缺失的FK指令从identity模式添加到KB模式中,在KB DB上下文中的EF modelBuilder中进行操作。就像只有1个上下文一样,但我将其分成了2个。
modelBuilder.Entity<Topic>(entity =>
{
entity.HasOne(d => d.Creator)
.WithMany(p => p.TopicCreator)
.HasForeignKey(d => d.CreatorId)
.HasConstraintName("fk_topic_app_users");
它没有起作用,因为 kb db context 没有关于用户对象的任何信息,Postgres 返回错误relation "AppUsers" does not exist
。
选择语句没有关于模式、字段名称等的正确信息。
我几乎放弃了,但然后我注意到在运行dotnet ef dbcontext scaffold
时有一个开关“-d”。 它是-data-annotations的缩写 - 尽可能使用属性配置模型。 如果省略,则仅使用流利的API。
指定此开关后,对象属性不是在db context OnModelCreating()
中定义的,而是在对象本身上,使用属性。
TL;DR: 单独的DB上下文无法很好地处理它们之间的关系(FK),每个上下文只有关于自己的实体的信息。
当在dotnet ef dbcontext scaffold
上指定"-data-annotations"开关时,这些信息不会存储在每个单独的上下文中,而是存储在DB对象本身上。