我有以下示例架构:
public class CounterReading
{
public int CounterReadingId { get; set; }
public virtual Counter Counter { get; set; }
public DateTime Date { get; set; }
public decimal Reading { get; set; }
public CounterReading()
{
Date = DateTime.Now;
}
}
public class Counter
{
[Key, ForeignKey("Meter")]
public int CounterId { get; set; }
public virtual Meter Meter { get; set; }
public virtual ObservableCollection<CounterReading> Readings { get; set; }
[NotMapped]
public CounterReading CurrentReading
{
get
{
if(Readings.Count > 0)
{
return Readings.MaxBy(m => m.Reading);
}
return null;
}
}
}
public abstract class Meter
{
public int MeterId { get; set; }
public string EANNumber { get; set; }
public string MeterNumber { get; set; }
public virtual Premise Premise { get; set; }
}
public class WaterMeter : Meter
{
public virtual Counter Counter { get; set; }
public WaterMeter()
{
Counter = new Counter();
Counter.Readings = new ObservableCollection<CounterReading>();
}
}
当我从数据库加载WaterMeter
时,我的CounterReadings
没有任何Counter
,这是行不通的。这是因为我在构造函数中设置了NullReferencesExceptions
,以便在运行时创建新的WaterMeter
时避免WaterMeter
。
如果我删除了{{1}}构造函数,EF会很好地加载我的读数。但这意味着我在使用我的应用程序时会有大量的NullReferences,而不是每次都重新加载我的数据。
解决这个问题的最佳方法是什么?
编辑: NRE:
答案 0 :(得分:1)
首先,您的问题中的代码和您正在执行的实际代码(根据您添加的图像)存在脱节,这就是我无法查看问题的原因。
但是,从您发布的图片中可以清楚地看出问题在于您Readings
为private
字段 - EF CodeFirst要求将导航属性标记为{{ 1}}以便初始化它们。
答案 1 :(得分:0)
要避免带有集合的空引用异常,您应该引入本地只读集合字段并将其初始化为空集合。
public class Counter
{
private readonly ObservableCollection<CounterReading> readings = new ObservableCollection<CounterReading>();
public virtual ObservableCollection<CounterReading> Readings
{
get { return readings; }
set { readings = value; }
}
[Key, ForeignKey("Meter")]
public int CounterId { get; set; }
public virtual Meter Meter { get; set; }
[NotMapped]
public CounterReading CurrentReading
{
get
{
return Readings.MaxBy(m => m.Reading);
}
}
}
答案 2 :(得分:0)
我对Evgeny的答案有一个补充。您可以有条件地创建集合的新实例,而不是始终创建集合的新实例,因此它只在实际调用此属性时创建新实例:
private readonly ObservableCollection<CounterReading> readings;
public virtual ObservableCollection<CounterReading> Readings
{
get
{
if(_readings == null)
{
_readings = new ObservableCollection<CounterReading>();
}
return readings;
}
set { readings = value; }
}
如果您不需要为getter和setter添加逻辑,为什么不考虑使用它:
public virtual ObservableCollection<CounterReading> Readings {get;set;}