如何返回IQueryable <t>以进一步查询</t>

时间:2013-05-08 17:57:16

标签: c# .net asp.net-mvc visual-studio asp.net-mvc-4

我正在尝试使用此处的PagedList.Mvc库

https://github.com/TroyGoode/PagedList

有这个用法样本

var products = MyProductDataSource.FindAllProducts(); //returns IQueryable<Product> representing an unknown number of products. a thousand maybe?

        var pageNumber = page ?? 1; // if no page was specified in the querystring, default to the first page (1)
        var onePageOfProducts = products.ToPagedList(pageNumber, 25); // will only contain 25 products max because of the pageSize

MyProductDataSource.FindAllProducts()的典型意义;

public IQuerable<T> MyProductDataSource.FindAllProducts()
{
   using ( var ctx = new MyCtx() )
   {
       return ctx.MyList().Where( .... );
   }
}

当然有InvalidOperationException()和DBContext已经处理消息

寻找有关如何返回IQueryable的最佳实践,可以在这里使用而不会出现问题?

2 个答案:

答案 0 :(得分:4)

好的做法是使用IoC容器将DbContext的生命周期保留为每个HTTP请求,大多数IoC容器都支持HttpRequest生存期。

因此,您可以利用DbContext的范围,允许您在上层使用IQueryable

更多信息我喜欢哪两个IoC容器: autofac ninject

autofac如何here

支持MVC

NInject

here如何支持MVC

如果您是IoC容器的新手,建议您查看Martin Flower的dependency injection基本概念。然后继续使用您选择的一个IoC容器。

但是,你需要非常小心如何使用IQueryable以及你应该停止支持它的哪一层。如果没有,后面的恶魔,实体框架中的延迟加载会降低性能。我的一条规则是不支持{。}上的IQueryable

答案 1 :(得分:3)

您需要“向上移动”数据上下文的范围:

public IQueryable<T> MyProductDataSource.FindAllProducts(MyCtx context)
{
    return context.MyList().Where( .... );
}

然后在更大的范围内创建上下文:

using (var ctx = new MyCtx())
{
    var products = MyProductDataSource.FindAllProducts(ctx);

    var pageNumber = page ?? 1;
    var onePageOfProducts = products.ToPagedList(pageNumber, 25);
}