我有一个使用EF作为ORM的应用程序。数据库过去只有一个模式dbo,一切都很好。我最近将我的表组织成4种不同的模式。一个模式的某些表依赖于位于另一个模式上的表。所有这些在SQL方面似乎都是有效的。
在应用程序方面,所有通过EF进行的数据库交互都不再有效。代码编译,模式在解决方案中可见,模型映射指向正确的模式,但一旦我尝试将行插入表,它就不起作用。
我看过一些关于使用多个模式将需要使用多个DBContext的文章,但我宁愿使用一个DBContext。我的所有模式都有相同的所有者dbo,我看不出使用多个DBContexts的原因。
有人知道是否有办法做到这一点吗?
您只能通过流畅的映射将每个表映射到自己的模式。在DbContext
子类型中,您应该覆盖OnModelCreating
(如果您还没有这样做的话),并添加如下语句:
modelBuilder.Entity<Department>()
.ToTable("t_Department", "school");
您没有像这样明确映射的实体将被放置在默认的dbo
模式中,或者您可以通过提供自己的默认值
modelBuilder.HasDefaultSchema("sales");
(从这里总结)
除了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);
});
以上内容将获取名称空间的最后一个组件,并将其用作模式名称。这就避免了为每个实体定制表绑定的需要。
在我的情况下,可能是我使用DB First生成EDMX文件,所以它不会调用OnModelCreating
方法。
我最终删除了EDMX文件中的所有store:Schema="YourSchema"
和Schema="YourSchema"
,我通过如下所示用powershell command
编写一个bat
文件来完成,并在Projec Pre-Build Event
:中执行bat
powershell -Command "$varStr='store:Schema=""abcd""""'; $filePath='%~dp0SomeFolderSomeFile.edmx'; (gc $filePath) -replace $varStr, '' | Out-File $filePath"