c# - Entity Framework Code First - select based on type of child TPH class -


i working entity framework 4 on project using table per hierarchy represent 1 set of classes using single table. way works table represents states , different states associated different other classes.

so might imagine this, ignoring common fields states share:

inactivestate    has -> statestore  activestate    has -> activitylocation  completedstate   has -> completiondate 

each state has collection of inventoryitems belong it.

now each item in inventory has many states, last 1 in history current state. save on lists have shortcut field points current state of inventory:

public class inventoryitem : entity {      // whole bunch of other properties      public virtual icollection<inventorystate> statehistory { get; set; }      public virtual inventorystate laststate { get; set; }  } 

the first problem having when want find, example, inventoryitems in active state.

it turns out linq-to-entities doesn't support gettype() can't use statement inventoryrepository.get().where( x => x.laststate.gettype() == sometype ). can use is operator, requires fixed type rather being able have method this:

 public icollection<inventoryitem> getinventoryitemsbystate( type state )  {      return inventoryrepository.get().where( x => x.laststate state );  } 

i have run kind of if statement based on type before make linq query, feels wrong. inventoryitem list large, need @ ef level, can't pull whole list memory , use gettype(), example.

i have 2 questions in situation, connected closely enough think can combined reflect lack of understanding on part:

  • is possible find list of items share child table type using linq entities?
  • given not using lazy loading, possible include related items child table types using tph that, example, if have inactivestate child of inventoryitem can preload statestore inactivestate?

is possible find list of items share child table type using linq entities?

i don't think it's possible in way using if/switch checks type , builds filter expression using is t or oftype<t>. encapsulate logic extension method example have single place maintain , reusable method:

public static class extensions {     public static iqueryable<inventoryitem> whereislaststate(         iqueryable<inventoryitem> query, type state)     {         if (state == typeof(inactivestate))             return query.where(i => i.laststate inactivestate);         if (state == typeof(activestate))             return query.where(i => i.laststate activestate);         if (state == typeof(completedstate))             return query.where(i => i.laststate completedstate);          throw new invalidoperationexception("unsupported type...");     } } 

to used this:

public icollection<inventoryitem> getinventoryitemsbystate(type state) {    return inventoryrepository.get().whereislaststate(state).tolist(); } 

i don't know if possible build i => i.laststate xxx expression manually using .net expression api , based on type passed method. (would interest me too, honest, have no clue expression manipulation answer myself.)

given not using lazy loading, possible include related items child table types using tph that, example, if have inactivestate child of inventoryitem can preload statestore inactivestate?

i not sure if understand correctly eager loading include not support filtering or additional operations on specific included children.

one way circumvent limitation , still result in single database roundtrip using projection this:

var result = context.inventoryitems     .select(i => new     {         inventoryitem = i,         laststate = i.laststate,         statestore = (i.laststate inactivestate)             ? (i.laststate inactivestate).statestore             : null     })     .asenumerable()     .select(x => x.inventoryitem)     .tolist(); 

if query tracked query (which in example above) , relationships not many-to-many (they not in example) context fixup relationships when entities loaded context, inventoryitem.laststate , inventoryitem.laststate.statestore (if laststate of type inactivestate) set loaded entities (as if had been loaded eager loading).


Comments

Popular posts from this blog

Why does Ruby on Rails generate add a blank line to the end of a file? -

keyboard - Smiles and long press feature in Android -

node.js - Bad Request - node js ajax post -