2013-05-08 34 views
5

Tôi đang cố gắng thư viện PagedList.Mvc từ đâyLàm thế nào để trở lại IQueryable <T> để biết thêm truy vấn

https://github.com/TroyGoode/PagedList

trong đó có mẫu sử dụng này

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 điển hình của MyProductDataSource.FindAllProducts (); là dọc theo dòng của

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

trong đó tất nhiên có InvalidOperationException() và DBContext đã được xử lý thông điệp

Looking for thực hành tốt nhất về cách trở IQueryable mà có thể được sử dụng ở đây không có vấn đề?

+0

Đây KHÔNG phải là triển khai điển hình. Thông thường bạn tiêm một ngữ cảnh vào một lớp kho lưu trữ có nghĩa là bạn không bỏ đi ở cấp phương thức. –

+0

@WiktorZychla Tôi không đồng ý. Cả hai đều là các triển khai hữu ích. Khi có thể phạm vi ngữ cảnh cục bộ cho phương thức thì đó là điều có thể chấp nhận được, nhưng khi việc tạo truy vấn vượt quá phạm vi của phương thức đó không phải là một tùy chọn, trong trường hợp này bạn cần phải điều chỉnh phạm vi của ngữ cảnh như vậy rằng, bất kể nó ở đâu, nó bao gồm cả thời gian tồn tại của truy vấn đó. Các lập trình viên có thể hiểu được tuổi thọ của bất kỳ truy vấn cụ thể nào và phạm vi ngữ cảnh sao cho nó ở cùng "mức độ" đó, không nhiều hơn, không kém. – Servy

+0

@Servy: true nhưng trong hầu hết các trường hợp, ngữ cảnh của bạn là "per-http-context". Lưu ý rằng anh ta gắn thẻ câu hỏi với asp.net.Những gì bạn nói là một phần của một lý thuyết chung, ông cần một hướng dẫn chính xác cho kịch bản asp.net cụ thể của mình. –

Trả lời

3

Bạn cần phải "di chuyển lên" phạm vi bối cảnh dữ liệu của bạn:

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

Sau đó, tạo ra bối cảnh ở phạm vi lớn hơn:

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

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

Một cách khác là chèn ngữ cảnh vào nguồn dữ liệu chứ không phải vào từng phương thức của nó. –

+0

@WiktorZychla Vấn đề là tuổi thọ của ngữ cảnh cần được tăng lên để vượt quá tuổi thọ của truy vấn, mức độ cần thiết để đạt được điều đó có thể thay đổi tùy theo truy vấn. Nó có thể cần phải ở phạm vi của đối tượng đó, hoặc nó có thể không. – Servy

+0

Tôi nghĩ rằng nên có IQueryable

4

Các thực hành tốt là để giữ cho tuổi thọ của DbContext là theo yêu cầu HTTP bằng cách sử dụng vùng chứa IoC, hầu hết các thùng chứa IoC đều hỗ trợ tuổi thọ HttpRequest.

Vì vậy, bạn có thể tận dụng phạm vi của DbContext cho phép bạn sử dụng IQueryable trên lớp trên.

Thông tin khác mà hai vùng chứa IoC tôi thích: autofacninject.

Làm thế nào autofac hỗ trợ MVC trong here

Hoặc cách NInject hỗ trợ MVC trong here

Nếu bạn là người mới vào IoC container, bạn sẽ đề nghị bạn nên tham gia một cái nhìn khái niệm cơ bản của dependency injection từ Martin Flower. Sau đó đi trước với một trong những container IoC bạn chọn.

Nhưng, bạn cần phải rất cẩn thận về cách sử dụng IQueryable và lớp nào bạn nên dừng hỗ trợ nó. Nếu không, ma quỷ phía sau, tải chậm từ khung thực thể sẽ làm chậm hiệu suất. Một trong các quy tắc của tôi không hỗ trợ IQueryable trên Chế độ xem.

Các vấn đề liên quan