我是否在EF中获得了很好的名单

时间:2012-08-30 20:51:31

标签: c# entity-framework entity-framework-4.1

我仍然是实体框架的新手。如果问题是假的,请原谅我:) 我有一个域类,它从数据库中获取一些数据列表:

public IEnumerable<Item> GetItems()
        {
            return context.Items.ToList();
        }

此代码返回数据库中的所有项目 在网站上我使用分页,所以每页只需要10个项目 所以我做了这样的事情:

var model = itemsRepository.GetItems().
                    Where(x => x.CategoryId == categoryId).
                    OrderByDescending(x => x.CreatedOnDate).
                    Skip(0).
                    Take(pageSize);

现在我看到我在这里做了什么,我从db中取出所有项目并过滤它们 如果我在域中添加新方法并将以下代码放入其中,我会获得一些好处:

return context.Items.Where(x => x.CategoryId == categoryId).
                    OrderByDescending(x => x.CreatedOnDate).
                    Skip(0).
                    Take(pageSize);

4 个答案:

答案 0 :(得分:1)

是的,你应该。我假设您使用SQL作为上下文的后端,但是最终使用新方法构造的查询只会将这10条记录拉出来并将它们作为IEnumerable(延迟执行)返回而不是从数据库中提取所有内容,然后过滤掉前10个结果。

我认为使用延迟执行的第二个(新)方法会更好。

您是否也通过SQL事件探查器看到了性能的提升?

答案 1 :(得分:1)

是。您将获得的好处是,后一种情况下的LINQ查询将转换为SQL并在数据库中执行。因此,您的第一个示例将整个表加载到内存中 - 而第二个示例将在数据库中执行更高效的查询。

基本上,.ToList()打破了延迟执行 - 但是您可能还有意义返回IQueryable<T>而不是IEnumerable<T>,然后在上层处理它 - 这取决于您的要求。另外,请尝试阅读this question and answer

答案 2 :(得分:1)

您的代码中存在一些问题:

  1. 不要在context课程中使用变量,每次需要时,创建并处理它(使用):

    使用(var context = new ...) {    //做数据库的东西 }

  2. 请勿调用ToList(),获取所有项目,使用普通分页,然后调用ToList(类似于您的第二个样本,但使用,......)。

答案 3 :(得分:1)

第二种方法的问题是域现在与上下文耦合。这违背了存储库模式的主要目的之一。我建议您在存储库中使用第二种方法,在其中传递您想要检索的页码,然后将它们返回给您。在您的存储库中有类似

的内容
public IEnumerable<Item> GetItemsForPage(int pageNumber)
    {
        return context.Items.Where(x => x.CategoryId == categoryId).
                OrderByDescending(x => x.CreatedOnDate).
                Skip(pageNumber * pageSize).  //Note not always 0
                Take(pageSize);

    }

在您的域中,您将调用repository.GetItemsForPage()。这为您提供了延迟执行的好处,同时保持了域和上下文的分离。