我想使用 Mapping Properties of an Entity Type to Multiple Tables in the Database (Entity Splitting)同时使用 Mapping the Table-Per-Hierarchy (TPH) Inheritance ,因此我的模型映射代码如下:
modelBuilder
.Entity<Person>()
.HasKey(n => n.PersonId)
.Map(map =>
{
map.Properties(p => new { p.Name });
map.ToTable("dbo.Person");
})
.Map<Customer>(map =>
{
map.Requires("PersonType").HasValue("C");
map.Properties(p => new { p.CustomerNumber });
map.ToTable("dbo.Customer");
});
基于以下基础数据库模式:
create table dbo.Person
(
PersonId int not null identity(1,1) primary key,
PersonType char(1) not null,
Name varchar(50) not null
)
create table dbo.Customer
(
PersonId int not null references dbo.Person (PersonId),
CustomerNumber varchar(10) not null
)
但是,当 EF 尝试执行我的查询时:
ctx.People.ToList();
抛出以下异常信息:
Invalid column name 'PersonType'.
运行 SQL 配置文件时,它似乎试图在 dbo.Customer
的字段 PersonType
上使用值为 C
的谓词表,而不是在我的鉴别器所在的 dbo.Person
表上。
如果我使用一个或另一个功能,即只使用继承或只使用附加表映射,那么它可以工作,但我会放弃我的一些要求。
我正在做的事情可以用 EF Fluent API 完成吗?
感谢您的宝贵时间。
最佳答案
这可以通过在映射中涉及的所有表模式上创建 View 来实现:
create view dbo.vw_PersonExtended
as
select
p.Name, p.PersonId, p.PersonType, c.CustomerNumber
from
dbo.Person p
left join dbo.Customer c on c.PersonId=p.PersonId
并将此 View 映射到基类类型 Person
并删除派生类表映射,如下所示:
modelBuilder
.Entity<Person>()
.HasKey(n => n.PersonId)
.Map(map =>
{
map.Properties(p => new { p.Name });
map.ToTable("dbo.vw_PersonExtended");
})
.Map<Customer>(map =>
{
map.Requires("PersonType").HasValue("C");
map.Properties(p => new { p.CustomerNumber });
});
插入新实体会失败,因为 View 有多个基表,因此您必须使用 INSTEAD OF TRIGGER或使用 Fluent 代码将插入映射到存储过程:
modelBuilder
.Entity<Customer>()
.MapToStoredProcedures(map => map.Insert(i => i.HasName("usp_InsertCustomer")));
并插入存储过程示例:
create procedure dbo.usp_InsertCustomer
@Name varchar(50),
@CustomerNumber varchar(50)
as
begin
set nocount on
declare @id int
insert into dbo.Person (Name, PersonType)
values (@Name, 'C')
set @id = scope_identity()
insert into dbo.Customer (PersonId, CustomerNumber)
values (@id, @CustomerNumber)
select @id as PersonId
end
显然,这种方法的缺点是所有的管道工作都涉及到它的工作。
关于c# - 实体类型的 EF 映射属性到具有 TPH 继承的多个表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34094470/