entity framework - Materializing an ICollection structure containing subclasses -
i'm reviewing code written in ef 4 days because stands out during performance benchmarking.
the purpose of code materialize icollection<mybaseclass>
using entity framework (we're on ef 6.1).
the code exists because references present in specific subclasses aren't materialized when retrieving
public parent { public virtual icollection<mybaseclass>() base { get; set; } }
from database, when actual types stored subclasses of mybaseclass.
example subclass:
public suba : mybaseclass { public virtual icollection<options> ref1 { get; set; } }
currently, code this:
var parent = ctx.parents.include(p => p.base).where(...).single(); loadsubclasses(parent.base); ... private void loadsubclasses(ienumerable<mybaseclass> mybase) { foreach (var in mybase) { if (my suba) { this.entry(my).reference("ref1").load(); this.entry((suba)my).ref1).collection("options").load(); } else... // similar other subclasses } }
note icollection<mybaseclass>() base
contains mix of several concrete subclasses. there few hundred objects in icollection
.
is there more efficient way materialize base
?
it cannot said in advance if performance better (sometimes executing single complex query, sub collection includes may have negative impact), can minimize number of database queries k, k number of subclass types need additional includes.
you need base loadsubclasses
method on iqueryable<tbase>
representing base entities, , execute 1 query per each subclass type using oftype
filter:
private void loadsubclasses(iqueryable<mybaseclass> basequery) { // suba basequery.oftype<suba>() .include(x => x.ref1.options) .load(); // similar other subclasses }
the usage sample be:
var parent = ctx.parents.include(p => p.base).where(...).single(); loadsubclasses(ctx.entry(parent).collection(p => p.base).query());
or more generally:
var parentquery = ctx.parents.where(...); var parents = parentquery.include(p => p.base).tolist(); loadsubclasses(parentquery.selectmany(p => p.base));
Comments
Post a Comment