c# - Entity Framework is sometimes not loading the contents of Child Objects/Collections -
i've started have problem child collections in entity framework not being loaded lazy loading.
the prominent example of orders object - each order has 1 or more order lines associated (ie. list of products have been ordered , how many). sometimes, when program run, can open orders , order lines (for every order) blank. restart program, , might re-appear. it's pretty intermittent.
i have confirmed there no entries in child collection through logging & debugging:
private observablecollection<orderline> loadorderlines() { log.debug("loading {0} order lines...", this.model.orderlines.count); var result = new observablecollection<orderline>(); foreach (var orderline in this.model.orderlines) { result.add(orderline); } return result; }
sometimes "loading 0 order lines..." , "loading 4 order lines..." same order.
i can't use eager loading when load list of orders because don't want load order lines orders when few of them might ever opened - need keep loading fast possible , load things needed, hence lazy loading.
it's not orders object happening on, happens on other child collections too, effect same.
anybody have idea why ef doing , can fix it? it's huge problem - can't have empty order lines in program when should there!
extra info may or not of use:
this wpf mvvm application. data layer, shared website, uses repository/unit of work pattern.
in ordersrepository:
public ienumerable<order> getorders(datetime fromdate, datetime todate, ienumerable<string> sources, bool? paidstatus, bool? shippedstatus, bool? cancelledstatus, bool? pendingstatus) { if (sources == null) { sources = this.context.ordersources.select(s => s.sourceid); } return this.context.orders.where( o => o.orderdate >= fromdate && o.orderdate < todate && sources.contains(o.sourceid) && (!paidstatus.hasvalue || ((o.receiptid != null) == paidstatus.value)) && (!shippedstatus.hasvalue || ((o.shippeddate != null) == shippedstatus.value)) && (!pendingstatus.hasvalue || (o.ispending == pendingstatus.value)) && (!cancelledstatus.hasvalue || (o.cancelled == cancelledstatus.value))).orderbydescending( o => o.orderdate); }
the ordersviewmodel loads orders, creates orderviewmodel each 1 , puts them in observablecollection:
var orderslist = this.unitofwork.ordersrepository.getorders(this.filter).tolist(); foreach (var order in orderslist) { var viewmodel = this.viewmodelprovider.getviewmodel<orderviewmodel, order>(order); this.orders.add(viewmodel); }
lazy loading loading related entities automatically when acces navigation property. but, in case, you're not doing automatically, manually.
to so, can disable lazy loading, , use explicit loading, this:
context.entry(order).collection(o => o.orderlines).load();
(besides, using technique, can apply filters).
your problem lazy loading can consequence of long lived dbcontext
caches related entities @ given point in time, , reuses cache later, without hitting db, it's outdated. i.e. 1 dbcontext finds 3 order lines order , caches them. else, (outside db context), adds 2 new order lines order. access order lines first db context , outdated 3 order lines, instead of 5 there in db. there several ways in wich could, thoretically, reload/refresh cached data on dbcontext, can trouble. you'd rather use explicit loading suggested above. if see docs load method, can read this:
loads collection of entities database. note entities exist in context not overwritten values database.
however, safest option dispose dbcontext
, create new one. (read second sentence of block above).
Comments
Post a Comment