[英]Code First table per hierarchy mapping
我有一個Organisation
實體,代表可以是供應商 , 客戶或兩者兼有的業務 。
實體看起來像這樣:
public abstract class Organisation
{
public Organisation()
{
IsCustomer = false;
IsSupplier = false;
}
public int Id { get; set; }
public string Name { get; set; }
public bool IsSupplier { get; set; }
public bool IsCustomer { get; set; }
}
我創建了一個名為“ Customer
和Supplier
的組織子類,因為與我域中其他部分的Organisations
一起工作時,這將使事情變得更容易(例如,只有作為Supplier
的Organisation
才能與采購訂單相關聯)。
我創建了兩個從Organisation
類派生的類。
public class Supplier : Organisation
{
}
public class Customer : Organisation
{
}
接下來,我想告訴實體框架如何將這些類映射到表。 所有信息都將存儲在稱為“組織”的單個表中,因此我嘗試使用TPH(每個層次的表)映射。
這是我希望映射工作的方式:
Organisations
,我希望Entity Framework返回所有組織,而不管IsCustomer
和IsSupplier
屬性中的值如何。 Suppliers
,我希望實體框架返回IsSupplier = true
所有組織。 Customers
,我希望實體框架返回IsCustomer = true
所有組織。 對於組織而言,既要成為客戶又要成為供應商是有效的,因此我希望某些組織可以同時包含在Customer
和Supplier
查詢中。
這是我定義的配置類:
class OrganisationConfiguration : EntityTypeConfiguration<Organisation>
{
internal OrganisationConfiguration()
{
ToTable("Organisations");
HasKey(o => o.Id);
Map<Customer>(m =>
{
m.Requires("IsCustomer").HasValue(true);
});
Map<Supplier>(m =>
{
m.Requires("IsSupplier").HasValue(true);
});
}
}
這將導致DataException
與以下消息一起拋出:
錯誤3032:映射片段的問題從第59行開始:映射了條件成員'Organisation.IsSupplier',條件為'IsNull = False'。 刪除Organisation.IsSupplier上的條件,或從映射中刪除它。
我不確定如何解決此錯誤,甚至我想做的事也不確定,因為我所看到的所有示例都只有一個歧視列。 我不確定只要使用一個鑒別器就能達到我想要的結果,因為我需要區分客戶和供應商這兩個組織。
更新:
經過一些研究,似乎是我在我的Organisation
類中定義了IsSupplier
和IsCustomer
屬性的結果。 如果刪除這些屬性,則將正確構建數據庫並進行映射(Entity Framework在表中創建單獨的標識符)。
我已經用3個獨立的查詢(1個選擇Organisations
,1個選擇Customers
和1個選擇Suppliers
)對此進行了測試,這似乎為我提供了正確的結果,因此使我獲得了大約90%的解決方案。
我現在遇到的問題是,我需要一種從數據庫中選擇Customer
的方法,並且還需要將其設置為供應商(因為我沒有要設置的屬性)。
現在無法嘗試,但我認為只允許使用1個區分列。
public abstract class Organisation { ... //public bool IsSupplier { get; set; } //public bool IsCustomer { get; set; } public int SubType { get; set; } }
和
Map<Customer>(m => { m.Requires("SubType").HasValue<int>(1); }); Map<Supplier>(m => { m.Requires("SubType").HasValue<int>(2); });
您當然應該定義一個枚舉來替換int。
您已經知道了,但是
組織既是客戶又是供應商是有效的
....
因為我需要區分既是客戶又是供應商的組織。
這完全違背了基本的OOP原則。 實例不能是2個派生類型,C#不支持。
如果要實現此目的,則需要完全不同的設計。
我需要一種從數據庫中選擇一個客戶並設置為客戶的方法(因為我沒有要設置的屬性)。
您可以使用OfType<>
方法選擇客戶或供應商:
var c = new Customer(....);
myContext.Organisations.Add(c);
您可以簡單地將客戶添加到通用實體集中:
var c = new Customer(....); myContext.Organisations.Add(c);
通常,您不會在查詢中使用Discriminator屬性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.