私が使用したい(エンティティ分割)データベース内の複数テーブルへのエンティティタイプのマッピングのプロパティを同じ時間として使用しながら(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
いずれかの機能、つまり継承のみまたは追加のテーブルマッピングのみを使用すると、機能しますが、要件の一部が失われます。
EF Fluent APIを使用して私が行っていることを実行できますか?
御時間ありがとうございます。
これは、マッピングに関係するすべてのテーブルスキーマのビューを作成することで実現できます。
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
明らかに、このアプローチの欠点は、これを機能させるために必要なすべての配管作業です。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加