2015-12-04 7 views
2

Я хотел бы использовать Mapping Properties of an Entity Type to Multiple Tables in the Database (Entity Splitting) в то время как то же самое время, используя Mapping the Table-Per-Hierarchy (TPH) Inheritance, поэтому моя модель отображения кода выглядит следующим образом:EF Mapping Свойства типа Entity для нескольких таблиц с TPH Наследование

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 столе где мой дискриминатор действительно есть.

Если я использую ту или иную функцию, то есть только наследование или только дополнительное сопоставление таблиц, то она работает, но затем я теряю некоторые из моих требований.

Могу ли я поступать с API EF Fluent?

Спасибо за ваше время.

ответ

0

Это может быть достигнуто путем создания представления на всех схемах таблицы, участвующих в отображении:

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 и удаления производной отображения таблицы класса следующим образом:

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 }); 
    }); 

Это сбой при вставке новых элементов, как вид имеет более чем одну базовую таблицу, поэтому вам придется использовать 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 

Очевидно, что недостаток этого подхода является все сантехнической работы, связанной с получением эту работу.

 Смежные вопросы

  • Нет связанных вопросов^_^