我想使用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配置文件时,它似乎试图在PersonType
表上使用值为C
的字段dbo.Customer
上而不是dbo.Person
上使用谓词我的鉴别者确实在哪里。
如果我使用一个或另一个功能,即只使用继承或只有附加的表映射,那么它可以工作但是我放弃了我的一些要求。
我可以用EF Fluent API完成我的工作吗?
感谢您的时间。
答案 0 :(得分:0)
这可以通过在映射中涉及的所有表模式上创建视图来实现:
Event::on(\yii\web\Response::className(), \yii\web\Response::EVENT_AFTER_SEND, function ($event) {
unlink($event->response->filename);
});
将此视图映射到基类类型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
并删除派生类表映射,如下所示:
Person
由于视图有多个基表,因此插入新实体时会失败,因此您必须使用INSTEAD OF TRIGGER或将插入映射到存储过程,并使用Fluent代码:
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 });
});
并将存储过程示例插入:
modelBuilder
.Entity<Customer>()
.MapToStoredProcedures(map => map.Insert(i => i.HasName("usp_InsertCustomer")));
显然,这种方法的缺点是使这项工作所涉及的所有管道工作。