将 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 command
的 bat
文件来实现,如下所示,然后执行 bat
在 Projec Pre-Build Event
:
powershell -Command "$varStr='store:Schema=""abcd""""'; $filePath='%~dp0SomeFolder\SomeFile.edmx'; (gc $filePath) -replace $varStr, '' | Out-File $filePath"
我有一个使用 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 command
的 bat
文件来实现,如下所示,然后执行 bat
在 Projec Pre-Build Event
:
powershell -Command "$varStr='store:Schema=""abcd""""'; $filePath='%~dp0SomeFolder\SomeFile.edmx'; (gc $filePath) -replace $varStr, '' | Out-File $filePath"