将 Entity Framework 6 与多个数据库模式一起使用,但使用一个 DBContext

Using Entity Framework 6 with Multiple DB Schemas but using One DBContext

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

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

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

有谁知道有没有办法实现这个?

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

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

您未像这样明确映射的实体将放置在默认 dbo 模式中,或者您可以通过

提供自己的默认值
modelBuilder.HasDefaultSchema("sales");

(摘自here

除了 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; }
}

@GertArnold 的回答很准确。然而,对于纯语法糖果,您也可以通过约定从模型的命名空间中提取模式来做到这一点。我们发现这对处理多个模式很有用

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

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

好的,你把模式设置为 class header 等等,但是你在哪里定义那个模式?例如:

[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 或者在哪里?

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

我最终删除了 EDMX 文件中的所有 store:Schema="YourSchema"Schema="YourSchema",我通过编写一个带有 powershell commandbat 文件来实现,如下所示,然后执行 batProjec Pre-Build Event:

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