使用具有多个 DB 模式但使用一个 DBContext 的 Entity Framework 6

Posted

技术标签:

【中文标题】使用具有多个 DB 模式但使用一个 DBContext 的 Entity Framework 6【英文标题】:Using Entity Framework 6 with Multiple DB Schemas but using One DBContext 【发布时间】:2016-08-03 06:46:01 【问题描述】:

我有一个使用 EF 作为 ORM 的应用程序。数据库曾经有一个模式,dbo,一切正常。我最近将我的表组织成 4 个不同的模式。一个模式的某些表依赖于驻留在不同模式上的表。在 SQL 方面,一切似乎都是有效的。

在应用程序端,所有通过 EF 进行的数据库交互都不再起作用。代码编译,架构在解决方案中可见,模型映射指向正确的架构,但是一旦我尝试向表中插入一行,它就不起作用了。

我看过一些关于使用多个模式的帖子需要使用多个 DBContext,但我宁愿使用一个 DBContext。我所有的模式都有相同的所有者 dbo,我没有看到使用多个 DBContext 的原因。

有谁知道有没有办法做到这一点?

【问题讨论】:

在这里查看mehdi.me/ambient-dbcontext-in-ef6。您将在一个地方管理所有 dbcontexts。 我想用一个dbcontext! 【参考方案1】:

在我的例子中,我可能使用 DB First 来生成我的 EDMX 文件,所以它没有调用 OnModelCreating 方法。

我终于删除了EDMX文件中的所有store:Schema="YourSchema"Schema="YourSchema",我通过写一个bat文件和powershell command如下,并在Projec Pre-Build Event中执行bat

powershell -Command "$varStr='store:Schema=""abcd""""'; $filePath='%~dp0SomeFolder\SomeFile.edmx'; (gc $filePath) -replace $varStr, '' | Out-File $filePath"

【讨论】:

为什么需要移除架构?为什么会这样生成? store:Schema="YourSchema"会指定具体的DB名,所以一般不能连接其他DB。【参考方案2】:

好的,您将架构或类标头等放在哪里,但您在哪里定义该架构?例如:

[Table("Test", Schema = "test1")]
public class Test

    public int Id  get; set; 


[Table("Test2", Schema = "test2")]
public class Test2

    public int Id  get; set; 

但是在哪里放置 test1 和 test2?不同的 DbContexts 或在哪里?

【讨论】:

【参考方案3】:

@GertArnold 的回答很到位。但是,对于纯语法糖果,您也可以通过约定从模型的名称空间中提取模式来执行此操作。我们发现这对处理多个模式很有用

modelBuilder.Types().Configure(e => 
        var schema = e.ClrType.Namespace.Split('.').Last().ToLower();
        var name = entity.ClrType.Name;
        return entity.ToTable(name, schema);
);

上面将采用命名空间的最后一个组件并将其用作架构名称。这避免了为每个实体自定义表绑定的需要。

【讨论】:

您能否详细说明或举一个更完整的例子?【参考方案4】:

除了 Gert Arnold 的响应,你还可以在你的实体中使用 Table 属性:

using System.ComponentModel.DataAnnotations.Schema;

[Table("t_Department", Schema = "school")]
public class Department

    public int Id  get; set; 

    public string Name  get; set; 

【讨论】:

【参考方案5】:

您只能通过流畅的映射将每个表映射到其自己的架构。在您的 DbContext 子类型中,您应该覆盖 OnModelCreating(如果您还没有这样做的话)并添加如下语句:

modelBuilder.Entity<Department>()  
    .ToTable("t_Department", "school");

您没有像这样显式映射的实体将被放置在默认的 dbo 架构中,或者您可以通过以下方式提供自己的默认值

modelBuilder.HasDefaultSchema("sales");

(总结自here)

【讨论】:

我不知道它是否在此期间发生了变化,或者我明显不正确,但它不是流畅的映射。也可以使用数据注解,[Table("t_Department", Schema = "school")]

以上是关于使用具有多个 DB 模式但使用一个 DBContext 的 Entity Framework 6的主要内容,如果未能解决你的问题,请参考以下文章

在 flask-sqlalchemy 中使用具有相同模型的多个数据库

具有多个 MySql 模式的实体框架多个 DbContext

您如何使用具有多个突变的自定义文件正确播种 prisma DB?

使用多个数据库各自具有一个模式,还是使用一个数据库具有多个模式更好?

业务和日志数据由 DB 或 Schema 分隔?

SQLITE DB如何将多个表的数据保存在一个文件中?