我通过使用Table Per Hierarchy(TPH)定义了一个名为Variable和派生类的实体。 Base类“Variable”包含PropertyValues的集合:
private ICollection<PropertyValue> propertyValues;
public const string DiscriminatorColumn = "Discriminator";
public const string Table = "Variables";
public VariableType VariableType { get; set; }
public string Name { get; set; }
[NotMapped]
public string Discriminator { get; set; }
public virtual ICollection<PropertyValue> PropertyValues
{
get { return this.propertyValues ?? (this.propertyValues = new ObservableCollection<PropertyValue>()); }
set { SetProperty(ref this.propertyValues, value, () => PropertyValues); }
}
现在,我想派生一个SpecialVariable类(或多个),它定义一些SpecialProperties(例如HighLimit),它应该映射到PropertyValues(table)中的一个条目。
public class MySpecialVariabe : Variable
{
public double HighLimit { get; set; }
}
我的OnModelCreating函数目前看起来像这样:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Variable>().HasKey(x => new { x.Id });
modelBuilder.Entity<Variable>()
.Map<MySpecialVariabe>(m => m.Requires(Variable.DiscriminatorColumn).HasValue(typeof(MySpecialVariabe).Name))
.Map<MySpecialVariabe2>(m => m.Requires(Variable.DiscriminatorColumn).HasValue(typeof(MySpecialVariabe2).Name)).ToTable(Variable.Table);
}
有人可以给我一些如何实现这一点的提示,而不会在派生类中编写大量不好看的代码。 (表现并不重要。)
最好的问候,
克里斯
答案 0 :(得分:1)
您无法将属性映射到记录。这就是我理解你的问题的方式。您有一些PropertyValues表,很可能是某些键/值对,并且您希望将实体属性作为记录(数据)映射到此表。这不是EF为你做的事情。您必须提供未映射的属性,这些属性将与propertyValues集合中的正确记录一起使用。
类似的东西:
[NotMapped]
public double HighLimit
{
get
{
var current = propertyValues.SingleOrDefault(p => p.Key == "HighLimit");
return current != null ? current.Value : 0.0;
}
set
{
var current = propertyValues.SingleOrDefault(p => p.Key == "HighLimit");
if (current != null)
{
current.Value = value;
}
else
{
propertyValues.Add(new PropertyValue { Key = "HighLimit", Value = value });
}
}
}
此方法的问题在于您无法在Linq-to-entities查询中使用HighLimit - 您必须始终使用PropertyValues。
此外,EF中的TPH要求派生实体(MySpecialVariable)的属性映射到与父实体(变量)相同的表。您不能将派生实体的属性映射到存储在其他表(PropertyValues)中的数据。