实体框架映射多个级别属性

实体框架映射多个级别属性

问题描述:

我试图在实体框架中实现分层继承结构,专门用于设置。例如,假设我们有用户首选项:实体框架映射多个级别属性

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中实现加载?

在你的基类添加默认属性值:

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对象,如果您希望从数据库中获得该对象,它将不得不分开。 –

只要属性是公共的,企业不会有问题作为默认值从另一个表中提取数据。你需要创建一个私有字段来保存数据,如果你使用一个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; } 
} 

这只是一个构造函数的选择,如果你需要在二传手的逻辑更多的控制权,否则奥斯汀的回答会更简单实施