我正在尝试使用此处的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的最佳实践,可以在这里使用而不会出现问题?
答案 0 :(得分:4)
好的做法是使用IoC容器将DbContext的生命周期保留为每个HTTP请求,大多数IoC容器都支持HttpRequest生存期。
因此,您可以利用DbContext的范围,允许您在上层使用IQueryable
。
更多信息我喜欢哪两个IoC容器: autofac 和 ninject 。
支持MVC 中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);
}