实体框架映射多个级别属性
问题描述:
我试图在实体框架中实现分层继承结构,专门用于设置。例如,假设我们有用户首选项:实体框架映射多个级别属性
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; }
}
答
只要属性是公共的,企业不会有问题作为默认值从另一个表中提取数据。你需要创建一个私有字段来保存数据,如果你使用一个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; }
}
这只是一个构造函数的选择,如果你需要在二传手的逻辑更多的控制权,否则奥斯汀的回答会更简单实施
这是硬编码的默认值。我希望它们在数据库中,以便可以更改默认值 –
您可以让Preference默认它自己的对象,比如'DefaultPreference',然后在构造函数中设置默认值? –
我刚刚更新了答案,以反映一个DefaultPreference对象,如果您希望从数据库中获得该对象,它将不得不分开。 –