2017-04-17 120 views
0

我試圖在實體框架中實現分層繼承結構,專門用於設置。例如,假設我們有用戶首選項:實體框架映射多個級別屬性

public class StorePreference: Preference { } 

public class UserPreference : Preference { } 

public class Preference { 
public string BackgroundColor { get; set; } 
public ContactMethod ContactMethod { get; set; } 
} 

public enum ContactMethod { 
    SMS, 
    Email 
} 

我喜歡它,所以如果我查找用戶的偏好。如果用戶不存在或者屬性值爲空,則查找父級(存儲)默認首選項。

理想的情況下,我想它的工作方式與抽象繼承:

public class UserPreference : StorePreference { 
    private string _backgroundColor; 

    public string BackgroundColor { 
     get { 
      if (this._backgroundColor == null) 
       return base; 

      return this._backgroundColor; 
     } 
     set { this._backgroundColor = value; } 
    } 
} 

如果我寫這一個SQL查詢語句,它會是一個十字CASE語句適用於:

SELECT 
    CASE WHEN User.BackgroundColor == null THEN Store.BackgroundColor ELSE User.BackgroundColor END BackgroundColor, 
    CASE WHEN User.ContactMethod == null THEN Store.ContactMethod ELSE User.ContactMethod END ContactMethod 
FROM UserPreference User 
CROSS APPLY StorePreference Store 
WHERE UserPreference.UserId = @UserId 

有沒有一種方法可以在EF中實現加載?

回答

0

在你的基類添加默認屬性值:

public class Preference { 
    public string BackgroundColor { get; set; } = "Red"; 
    public ContactMethod ContactMethod { get; set; } = ContactMethod.SMS; 
} 

事情是這樣的,從數據庫中設置:

public class StorePreference : Preference { } 

public class UserPreference : Preference { } 

public class Preference { 
    public Preference() { 
     BackgroundColor = DefaultPreference.BackgroundColor; 
     ContactMethod = DefaultPreference.ContactMethod; 
    } 

    public string BackgroundColor { get; set; } 
    public ContactMethod ContactMethod { get; set; } 

    public DefaultPreference DefaultPreference { get; set; } 
} 

public class DefaultPreference { 
    public string BackgroundColor { get; set; } 
    public ContactMethod ContactMethod { get; set; } 
} 
+0

這是硬編碼的默認值。我希望它們在數據庫中,以便可以更改默認值 –

+0

您可以讓Preference默認它自己的對象,比如'DefaultPreference',然後在構造函數中設置默認值? –

+0

我剛剛更新了答案,以反映一個DefaultPreference對象,如果您希望從數據庫中獲得該對象,它將不得不分開。 –

0

只要屬性是公共的,企業不會有問題作爲默認值從另一個表中提取數據。你需要創建一個私有字段來保存數據,如果你使用一個setter:

public class ChildTable : EntityBase { 
    private string _someCategory; 

    [Key] 
    [Column(name: "CHILD_ID")] 
    public override int Id { get; protected set; } 

    [Column(name: "SOME_CATEGORY")] 
    public string SomeCategory { 
     get { return _someCategory; } 
     set { _someCategory = value ?? ParentTable.SomeCategory; } 
    } 

    [ForeignKey("ParentTable")] 
    [Column(name: "PARENT_ID")] 
    public int ParentTableId { get; set; } 

    public virtual ParentTable ParentTable { get; set; } 
} 

這只是一個構造函數的選擇,如果你需要在二傳手的邏輯更多的控制權,否則奧斯汀的回答會更簡單實施