我有一个使用 EF 作为 ORM 的应用程序。数据库曾经有一个模式,dbo,一切都工作正常。我最近将表组织成 4 种不同的模式。一个模式的某些表依赖于驻留在不同模式中的表。一切似乎在 SQL 端都是有效的。
在应用程序端,通过 EF 的所有数据库交互都不再起作用。代码编译后,架构在解决方案中可见,模型映射指向正确的架构,但是一旦我尝试向表中插入一行,它就不起作用。
我看过一些关于使用多个模式的帖子需要使用多个 DBContext,但我宁愿使用一个 DBContext。我的所有模式都有相同的所有者 dbo,我没有看到使用多个 DBContext 的原因。
有谁知道是否有办法实现这一目标?
您可以仅通过流畅映射将每个表映射到其自己的模式。在您的
DbContext
子类型中,您应该覆盖 OnModelCreating
(如果您还没有这样做)并添加如下语句:
modelBuilder.Entity<Department>()
.ToTable("t_Department", "school");
您未像这样显式映射的实体将被放置在默认的
dbo
架构中,或者您可以通过 提供您自己的默认值
modelBuilder.HasDefaultSchema("sales");
(总结自这里)
除了 Gert Arnold 的响应之外,您还可以在实体上使用表属性:
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);
});
上面将采用命名空间的最终组成部分并将其用作模式名称。这避免了为每个实体自定义表绑定的需要。
就我而言,我可能使用 DB First 来生成 EDMX 文件,因此它不会调用
OnModelCreating
方法。
我最终删除了 EDMX 文件中的所有
store:Schema="YourSchema"
和 Schema="YourSchema"
,我通过如下方式编写带有 bat
的 powershell command
文件,并执行 bat
中的 Projec Pre-Build Event
:
powershell -Command "$varStr='store:Schema=""abcd""""'; $filePath='%~dp0SomeFolder\SomeFile.edmx'; (gc $filePath) -replace $varStr, '' | Out-File $filePath"