实体框架映射多级属性

时间:2017-04-17 20:17:15

标签: c# entity-framework cross-apply

我正在尝试在Entity Framework中实现层次结构继承结构,特别是用于设置。例如,假设我们有用户首选项:

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
}

如果我查找用户的偏好,我会喜欢它。如果用户不存在或属性值为null,则会查找父(存储)默认首选项。

理想情况下,我希望它与抽象继承类似:

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语句的CROSS APPLY:

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

2 个答案:

答案 0 :(得分: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; }
}

答案 1 :(得分:0)

只要属性是公共的,实体就不会有问题从另一个表中提取数据作为默认值。如果您使用了setter,则需要创建一个私有字段来保存数据:

callback($events);

如果您需要更多地控制setter逻辑,这只是构造函数的替代方案,否则Austin的答案将更容易实现