我有实体“Ideas”,它有子实体集合“ChildIdeas”。我需要加载想法列表和“ChildIdeas”的计数(仅计数!)。 我能做到:
急切加载
from i in _dataContext.Ideas.Include("ChildIdeas") ...
优点:一个请求获得所有必要的数据; 缺点:加载不必要的数据。我只需要计算ChildIdeas,而不是完整的ChildIdeas列表
明确加载
from i in _dataContext.Ideas ...
idea.ChildIdeas.Loading()
优点:无; 缺点:许多请求(ideas.count + 1)而不是一个,加载不必要的数据
独立请求
from i in _dataContext.Ideas ...
_repository.GetCountChildIdeas(idea.ID);
优点:只加载必要的数据;
缺点:许多请求(ideas.count + 1)而不是一个
所有3种类型都有缺点。也许存在任何方式只加载必要的数据?如果是的话 - 它是什么,如果没有 - 哪种方式最适合这种情况?
[ADDED] 在负载测试后(对于1个用户)我得到了页面加载(以秒为单位): 渴望儿童的想法 - 1.31秒 明确的儿童想法 - 1.19秒 外部请求 - 1.14秒
所以,对我的情况急切的方式是最糟糕的......为什么甚至明确的方式更好?
答案 0 :(得分:2)
你应该使用投影。 {1}个子提示不属于持久性Count
实体,因此请创建包含Idea
实体和Idea
属性中所有属性的新非映射类型。
Count
现在,您可以使用简单的投影查询来获取单个请求的所有内容,而无需加载任何其他数据:
public class IdeaProjection
{
public int Id { get; set; }
// Other properties
public int Count { get; set; }
}
缺点是var query = from x in context.Ideas
where ...
select new IdeaProjection
{
Id = x.Id,
// Mapped other properties
Count = x.ChildIdeas.Count()
};
不是实体,如果你想将它用于更新,你必须将它转换回Idea并告诉EF有关更改。从性能角度来看,最好从EF处获得,而不必恢复到SQL或存储过程。