2

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

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

4 回答 4

1

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

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

您是否也通过 SQL Profiler 看到了性能的改进?

于 2012-08-30T20:55:43.947 回答
1

是的。您将受益于后一种情况下的 LINQ 查询将被转换为 SQL 并在数据库中执行。因此,您的第一个示例会将整个表加载到内存中 - 而第二个示例将在数据库中进行更有效的查询。

从本质上讲,.ToList()中断延迟了执行——但你也可以返回IQueryable<T>而不是返回IEnumerable<T>,然后在上层处理它——这取决于你的要求。另外,请尝试阅读此问题和答案

于 2012-08-30T20:56:22.100 回答
1

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

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

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

  2. 不要调用ToList(), 来获取所有项目,使用正常的分页然后调用 ToList (类似于你的第二个示例,但使用,...)。

于 2012-08-30T21:00:15.040 回答
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()。这为您提供了延迟执行的好处,同时保持了域和上下文的解耦。

于 2012-08-30T21:00:38.703 回答