我有一个TimeSeries<T>
包含通用状态变量列表的通用类State<T>
。State<T>
包含特定时间的状态。
public class TimeSeries<T>
{
[Key]
public int ID { get; set; }
public List<State<T>> States { get; set; }
}
public class State<T>
{
[Key]
public int StateID { get; set; }
public DateTime Date { get; set; }
public T State { get; set; }
}
此外,我有两个类IntClass
and FloatClass
,它们都包含一个时间序列,但类型不同。为了获取 TimeSeries 的两个表,其中一个有一个指向的外键,另一个有一个指向IntClass
的外键FloatClass
,我从 派生了两个类TimeSeries<T>
,每个类都包含一个外键属性。
public class IntTimeSeries : TimeSeries<int>
{
public int IntClassID{ get; set; }
}
public class FloatTimeSeries : TimeSeries<float>
{
public int FloatClassID{ get; set; }
}
IntClass
并FloatClass
包含派生类的实例:
public class IntClass
{
[Key]
public int ID { get; set; }
public IntTimeSeries TimeSeries { get; set; }
}
public class FloatClass
{
[Key]
public int ID { get; set; }
public FloatTimeSeries TimeSeries { get; set; }
}
这种方法生成表State<int>
和State<float>
. 它们分别具有(自动生成的)外键IntClassID
和FloatClassID
。如果我注释StateID
用[Key]
,因为我在这里做,那当然是主键。
然而,我想要的是主键分别是组合(Date, IntClassID)
和(Date, FloatClassID)
。我需要这个,因为我有时需要更新我只有读取权限的第二个数据库中的值。这可能吗?
在 EF-core 3 和 5 中,您可以通过修改 EF 的元数据来实现这一点,这些元数据在这些更高版本中很容易访问:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var stateTypes = modelBuilder.Model.GetEntityTypes()
.Where(e => e.ClrType.IsConstructedGenericType
&& e.ClrType.GetGenericTypeDefinition() == (typeof(State<>)))
.ToList();
stateTypes
.ForEach(t => t.SetPrimaryKey(t.FindProperties(new[] { "StateID", "Date"} )));
}
这首先收集派生自的实体类型,State<>
然后为这些类型设置主键属性。使用nameof
当然会使这在运行时更安全。
对于 EF core 2 用户,最后一条语句是:
stateTypes.ForEach(t => t.SetPrimaryKey(t.GetProperties()
.Where(p => new[] { "StateID", "Date" }.Contains(p.Name))
.OrderByDescending(p => p.Name)
.ToList()));
(OrderByDescending
因为在这种情况下,属性不是按数组顺序获取的)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句