C# 如何返回IQueryable<;T>;供进一步查询
我正在从这里尝试PagedList.Mvc库 哪个有这个用法示例C# 如何返回IQueryable<;T>;供进一步查询,c#,.net,asp.net-mvc,visual-studio,asp.net-mvc-4,C#,.net,Asp.net Mvc,Visual Studio,Asp.net Mvc 4,我正在从这里尝试PagedList.Mvc库 哪个有这个用法示例 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
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
var products=MyProductDataSource.FindAllProducts()//返回表示未知数量产品的IQueryable。也许一千?
变量pageNumber=第页??1; // 如果查询字符串中未指定页面,则默认为第一页(1)
var onePageOfProducts=products.ToPagedList(页码,25);//由于页面大小,最多只包含25个产品
MyProductDataSource.FindAllProducts()的典型实现;都是按照
public IQuerable<T> MyProductDataSource.FindAllProducts()
{
using ( var ctx = new MyCtx() )
{
return ctx.MyList().Where( .... );
}
}
public IQuerable MyProductDataSource.FindAllProducts()
{
使用(var ctx=new MyCtx())
{
返回ctx.MyList(),其中(…);
}
}
其中当然有InvalidOperationException()和DBContext已被释放的消息
寻找关于如何返回IQueryable的最佳实践,在这里使用IQueryable不会出现问题?您需要“向上移动”数据上下文的范围:
public IQueryable<T> MyProductDataSource.FindAllProducts(MyCtx context)
{
return context.MyList().Where( .... );
}
好的做法是使用IoC容器按照HTTP请求保持DbContext的生存期,大多数IoC容器都支持HttpRequest生存期 因此,您可以利用DbContext的作用域,它允许您在上层使用
IQueryable
更多信息我喜欢哪两个IoC容器:autofac和ninject
如何在中支持MVC
或者如何在中支持MVC
如果你对IoC容器是新手,你会建议你看看Martin Flower的基本概念。然后继续使用您选择的一个IoC容器
但是,您需要非常小心如何使用
IQueryable
,以及应该停止支持它的层。否则,从实体框架延迟加载将降低性能。我的规则之一是在视图中不支持IQueryable
。这不是一个典型的实现。通常,您会将上下文注入到存储库类中,这意味着您不会在方法级别进行处置。@WiktorZychla我不同意。两者都是有用的实现。当可以在本地将上下文范围限定到方法时,这是一件可以接受的事情,但是当查询的生成超出了该方法的范围(这不是一个选项)时,在这种情况下,您需要调整上下文的范围,以便无论在何处,它都包含该查询的生存期。程序员应该能够理解任何给定查询的生存期是什么,并确定上下文的范围,使其处于相同的“级别”,不多也不少。@Servy:true,但在大多数情况下,您的上下文生存期是“每个http上下文”。注意,他用asp.net标记了这个问题。你所说的只是一个一般的理论,他需要一个具体的asp.net场景的精确指导。@WiktorZychla生命周期将少于“每个http上下文”,因此,如果你在这个级别上定义上下文,它不太可能太窄。这就是说,在太宽的范围内确定上下文的范围也可能会有问题(它将在更长的时间内消耗更多的资源)。只要有可能,您就应该确保上下文的生存期与查询的生存期完全相同,或者只比查询的生存期大一点点,而不是总是在您知道的远远超出其需要的级别上确定上下文的范围。当然,如果性能不是问题……另一种选择是将上下文注入数据源,而不是注入数据源的每个方法。@WiktorZychla关键是上下文的生存期需要增加,以超过查询的生存期,当然,要达到这一目标需要达到多高的程度,可能会根据查询的不同而有所不同。它可能需要在该对象的范围内,也可能不在该对象的范围内。我认为这应该是可行的
using (var ctx = new MyCtx())
{
var products = MyProductDataSource.FindAllProducts(ctx);
var pageNumber = page ?? 1;
var onePageOfProducts = products.ToPagedList(pageNumber, 25);
}