Reputation: 1187
I have the following entities:
public abstract class Meter
{
public int MeterId { get; set; }
public string EANNumber { get; set; }
public string MeterNumber { get; set; }
public abstract void AddReading(CounterReading reading);
}
public abstract class ElectricityMeter : Meter { }
public class SingleElectricityMeter : ElectricityMeter
{
private Counter _counter = new Counter();
public virtual Counter Counter
{
get { return _counter; }
set { _counter = value; }
}
public override void AddReading(CounterReading reading)
{
Counter.Readings.Add(reading);
}
}
public class Counter
{
public int CounterId { get; set; }
private ObservableCollection<CounterReading> _readings = new ObservableCollection<CounterReading>();
public virtual ObservableCollection<CounterReading> Readings
{
get { return _readings; }
set { _readings = value; }
}
[NotMapped]
public CounterReading CurrentReading
{
get
{
return Readings.MaxBy(m => m.Reading);
}
}
}
When I set the Counter
relation in runtime, everything works perfect.
When I try to load the saved data, my Counter
object isn't loaded (it's the default Counter
, and not the one with the data from my database).
Is this still because I'm using inheritance in my Meter
?
My database looks decent enough with foreign keys:
Edit
Retrieving other nested entities works without problem.
Upvotes: 1
Views: 72
Reputation: 109253
SingleElectricityMeter.Counter
is a (reference) navigation property. In your code it is always initialized by
private Counter _counter = new Counter();
But you shouldn't initialize reference properties. EF will think they're loaded and won't load them from the database. So just remove the initialization. But be careful...
The encapsulation of adding readings in the top-level class is a good idea from an OO point of view, but in the context of Entity Framework (or any ORM) it comes with a caveat. In order to make this work you always have to ensure that a Meter
is read from the database including the Counter
and its Readings
:
db.Meters.Include(m => m.Counter.Readings)
As long as you do this, EF will be tracking all objects it needs in order to notice that Readings
causes a change it should store in the database.
Also, by doing so it is safe to access Counter.CurrentReading
. Otherwise this might trigger lazy loading (may not be bad, but can be inefficient) or cause an error if this happens after the context has been disposed.
Upvotes: 3