2013-05-08 49 views
5

我从这里如何返回的IQueryable <T>进一步查询

https://github.com/TroyGoode/PagedList

具有这种用法示例MyProductDataSource.FindAllProducts的

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 

典型implmentations尝试PagedList.Mvc库( );沿的

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

其中当然也有出现InvalidOperationException()和的DbContext已经配置消息

寻找如何返回的IQueryable可以在这里使用没有问题的最佳实践行?

+0

这不是一个典型的实现。通常情况下,您将一个上下文注入到存储库类中,这意味着您不会在方法级别进行处理。 – 2013-05-08 18:02:23

+0

@WiktorZychla我不同意。两者都是有用的实现。如果可以将上下文范围本地化为方法,这是可以接受的事情,但是当查询的生成超出了该方法的范围时(这不是一个选项),在这种情况下,您需要调整上下文的范围,例如无论它在哪里,它都包含该查询的生命周期。程序员应该能够理解任何给定查询的生命周期,并确定上下文的范围,使其处于同一“级别”,不多也不少。 – Servy 2013-05-08 18:04:52

+0

@Servy:true,但在大多数情况下,您的上下文生存期是“per-http-context”。请注意,他用asp.net标记问题。你所说的是一个普遍的理论,他需要一个精确的指导,为他的具体,asp.net场景。 – 2013-05-08 18:07:52

回答

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); 
} 
+0

另一种方法是将上下文注入到数据源中,而不是注入每个单一的方法中。 – 2013-05-08 18:03:21

+0

@WiktorZychla问题是,上下文的生命周期需要增加以超过查询的生命周期,您需要实现的程度有多高,当然可以根据查询而变化。它可能需要在该对象的范围内,否则可能不需要。 – Servy 2013-05-08 18:07:31

+0

我觉得应该是IQueryable 2017-11-27 22:01:40

4

好的做法是保持的寿命DbContext作为通过使用IoC容器的每个HTTP请求,大多数IoC容器支持HttpRequest生存期。

所以你可以利用DbContext的范围,它允许你在上层使用IQueryable

我喜欢其中两个IoC容器的更多信息:autofacninject

如何autofac支持MVC中here

还是怎么NInject支持MVC中here

如果你是IoC容器新的,你有什么建议,你应该看看的dependency injection从马丁花的基本概念。然后继续您选择的IoC容器之一。

但是,您需要非常小心如何使用IQueryable以及您应该停止支持哪一层。如果不是这样,那么魔鬼就落后了,从实体框架延迟加载会降低性能。我的一条规则是不支持View上的IQueryable

相关问题