实体框架,性能调优

时间:2011-10-08 11:24:11

标签: entity-framework entity performance

我有实体“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秒

所以,对我的情况急切的方式是最糟糕的......为什么甚至明确的方式更好?

1 个答案:

答案 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或存储过程。