Materialize entity framework query

前端 未结 2 1206
南方客
南方客 2020-12-12 05:07

I am using entity framework 5 for a query like this:

var query = 
    from i in context.Instrument
    from p in i.InstrumentPerformance  // 1 : n
    where          


        
相关标签:
2条回答
  • 2020-12-12 05:23

    Look at EntityCollection<T> CreateSourceQuery and Attach. I think you could do this (not tested):

    var instrumentQuery = 
        from i in context.Instrument
        from p in i.InstrumentPerformance  // 1 : n
        where p.PortfolioScenarioID == 6013
        select i;
    var instruments = instrumentQuery.ToList();
    foreach (var instrument in instruments) {
        var performanceQuery =
            instrument.InstrumentPerformance.CreateSourceQuery()
                .Where(p => p.PortfolioScenarioID == 6013);
        instrument.InstrumentPerformance.Attach(performanceQuery);
    }
    

    This executes everything at once (no lazy loading) and has a bit of code duplication, but it would result in a list of Instrument where each i.InstrumentPerformance returns the filtered collection, meaning any subsequent code that operates on it can treat it like any other EF collection without needing to know the details of the query.

    0 讨论(0)
  • 2020-12-12 05:36

    It is possible to retrieve the objects in one take first and then create the dictionaries by:

    var query = 
        (from i in context.Instrument
        select new { 
                     i,
                     ps = i.InstrumentPerformance
                              .Where(p.PortfolioScenarioID == 6013)
                   }).AsEnumerable()
                   .Select(x => x.i);
    

    This materializes and selects Instrument entities and, here's the trick, their partly loaded InstrumentPerformance collections. I.e. the instruments only contain InstrumentPerformance entities that meet the condition PortfolioScenarioID == 6013. This is because EF runs a process known as relationship fixup that ties child objects to the right parent object when they are fetched from the database.

    So now you can dispose the context and any time after that do

    var perf = query.First(i => i.InstrumentID == 407240).InstrumentPerformance;
    

    or build your dictionaries using from i in query in stead of from i in context.Instrument.

    IMPORTANT: lazy loading should be disabled, otherwise EF will still try to load the full collections when they are addressed.

    0 讨论(0)
提交回复
热议问题