Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何返回IQueryable<;T>;供进一步查询_C#_.net_Asp.net Mvc_Visual Studio_Asp.net Mvc 4 - Fatal编程技术网

C# 如何返回IQueryable<;T>;供进一步查询

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

我正在从这里尝试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 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);
}