c# - Entity Framework Linq set property of an object without additional projection by SELECT -
i'm implementing inheritance scenario entity framework 6. inheritance exists on dto level, i.e. have 2 classes foo
, bar : foo
, have first method selects iqueryable<foo>
, several methods select additional properties specific inheriting classes bar.
normally, have code
from foo in selectfoo() join baradditionalprops in ..... select new bar{ id = foo.id, description = foo.description, baz = baradditionalprops.baz}
which give nice single sql query result.
this, unfortunately, means properties foo have copied during second projection (first 1 inside selectfoo
). in real life code mean 20+ properties copied in every method using selectfoo
.
i (code prepared in linqpad, assume this
== efcontext):
void main() { (from barbase in selectt<bar>() join field in this.fields on barbase.id equals field.productid let _1 = barbase.baz = field.baz // part fails exception // expression tree may not contain assigment operator select barbase) .first() .dump(); } public iqueryable<t> selectt<t>() t : foo, new() { return .products .select(x => new t { id = x.id, description = x.description }); } public class foo { public string description {get;set;} public int id {get;set;} } public class bar : foo { public int baz {get;set;} }
receiving exception described above, i'm looking way make work or other solution allow me not copy base class properties during second projection.
since no existing tools job, wrote own library uses expression tree modification project baseclass dto in subclass dto automatically.
now instead of
iqueryable<basedto> basequery = getbasequery(); iqueryable<subclassdto> query = basedto in basequery let moredata = datacontext.vmoredata.firstordefault(x => x.id == basedto.id) select new subclassdto() { newprop1 = moredata.foo, newprop2 = moredata.baz, oldprop1 = moredata.someoverridingdata, oldprop2 = basedto.oldprop2, oldprop3 = basedto.oldprop3, oldprop4 = basedto.oldprop4, //... 20 more projections basedto subclassdto };
we have this
iqueryable<basedto> basequery = getbasequery(); iqueryable<subclassdto> query = basedto in basequery let moredata = datacontext.vmoredata.firstordefault(x => x.id == basedto.id) select basedto.autoprojectinto(() => new subclassdto() { newprop1 = moredata.foo, newprop2 = moredata.baz, oldprop1 = moredata.someoverridingdata }); iqueryable<subclassdto> activatequery = query.activateautoprojects();
and properties not bound subclassdto initialization projected basedto automatically.
library available via github https://github.com/ikoshelev/linq.autoproject , nuget https://www.nuget.org/packages/linq.autoproject
Comments
Post a Comment