簡體   English   中英

每個層次結構映射的代碼優先表

[英]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; }
}

我創建了一個名為“ CustomerSupplier的組織子類,因為與我域中其他部分的Organisations一起工作時,這將使事情變得更容易(例如,只有作為SupplierOrganisation才能與采購訂單相關聯)。

我創建了兩個從Organisation類派生的類。

public class Supplier : Organisation
{
}

public class Customer : Organisation
{
}

接下來,我想告訴實體框架如何將這些類映射到表。 所有信息都將存儲在稱為“組織”的單個表中,因此我嘗試使用TPH(每個層次的表)映射。

這是我希望映射工作的方式:

  • 如果我查詢Organisations ,我希望Entity Framework返回所有組織,而不管IsCustomerIsSupplier屬性中的值如何。
  • 如果我查詢Suppliers ,我希望實體框架返回IsSupplier = true所有組織。
  • 如果查詢Customers ,我希望實體框架返回IsCustomer = true所有組織。

對於組織而言,既要成為客戶又要成為供應商是有效的,因此我希望某些組織可以同時包含在CustomerSupplier查詢中。

這是我定義的配置類:

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類中定義了IsSupplierIsCustomer屬性的結果。 如果刪除這些屬性,則將正確構建數據庫並進行映射(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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM