Entity Framework, performance tuning
I have entity "Ideas", which has child entity collection "ChildIdeas". I need to load list of ideas and count of "ChildIdeas" (only count!). I can do:
eager loading
from i in _dataContext.Ideas.Include("ChildIdeas") ...
advantages : all necessary data got by one request; disadvantages : load unnecessary data. I need开发者_Go百科 only count of ChildIdeas, not full ChildIdeas list
Explicit loading
from i in _dataContext.Ideas ...
idea.ChildIdeas.Loading()
advantages : none; disadvantages : many requests (ideas.count + 1) instead of one, load unnecessary data
Independent requests
from i in _dataContext.Ideas ...
_repository.GetCountChildIdeas(idea.ID);
advantages : load only necessary data; disadvantages : many requests (ideas.count + 1) instead of one
all 3 types have disadvantages. Maybe is exist any way to load only necessary data? If yes - what is it, if no - which way is the best for this case?
[ADDED] after load testing (for 1 user) I got Page Load (in sec): eager Child Ideas - 1.31 sec explicit Child Ideas - 1.19 sec external requests - 1.14 sec
so, eager way for my case is the worst... Why even explicit way is better?
You should use projection. Count
of child ideas is not part of persisted Idea
entity so create new non-mapped type containing all properties from Idea
entity and Count
property.
public class IdeaProjection
{
public int Id { get; set; }
// Other properties
public int Count { get; set; }
}
Now you can use simple projection query to get everything with single request without loading any additional data:
var query = from x in context.Ideas
where ...
select new IdeaProjection
{
Id = x.Id,
// Mapped other properties
Count = x.ChildIdeas.Count()
};
Disadvantage is that IdeaProjection
is not entity and if you want to use it for updates as well you must transform it back to Idea and tell EF about changes. From performance perspective it is best you can get from EF without reverting back to SQL or stored procedures.
精彩评论