2011-06-20 15 views
8

Tôi đang sử dụng EF4 với mã đầu tiên và có một kho lưu trữ cho sự kiên trì và một lớp dịch vụ tương tác với nó. Tôi có một phương thức lớp dịch vụ gọi một phương thức IQueryable trên kho lưu trữ của tôi và trả về một IEnumerable chứa các thực thể. Tôi cũng cần trả lại tổng số bản ghi để tôi có thể tính toán các liên kết phân trang.Làm cách nào để hiển thị tổng số bản ghi và thu thập các bản ghi được thu thập từ phương thức lớp dịch vụ của IEnumable?

Làm cách nào để trả về cả int và IEnumerable từ phương thức dịch vụ của tôi?

  • Sử dụng một tham số ra vào phương pháp cho tổng hàng đếm
  • Tạo một lớp riêng biệt bao gồm tổng hàng được tính là một tài sản
  • Di chuyển các truy vấn phân trang LINQ ra khỏi lớp dịch vụ (lộ IQueryable từ repo trên lớp dịch vụ)
  • Tạo một phương thức riêng hoàn toàn trên lớp dịch vụ thực hiện truy vấn mới chỉ để đếm.

Tất cả những thứ này đều hiệu quả, nhưng cái nào sạch nhất?

CẬP NHẬT: Dưới đây là một số làm rõ kiến ​​trúc. Nếu điều này là sai, sau đó xin vui lòng cho tôi biết cách tốt hơn (ví dụ - làm phân trang trong lớp trình bày thay vì lớp dịch vụ, vv) lớp

Repo:

lợi nhuận IQueryable của DbSet, tóm tắt truy cập db từ các lớp trình bày

lớp dịch vụ:

không một truy vấn LINQ trên IQueryable để lọc và chỉ nhận được các mục trang như mong muốn bằng bỏ qua và mất và trả về một IEnumerable (đi cũng đặt vào danh sách trên trở lại để tránh bất kỳ vấn đề DbContext đời)

Presentation layer:

Gọi phương thức trên lớp dịch vụ (getPagedResults (bộ lọc, PAGENUMBER, PageSize))

Từ vẻ của nó tôi cũng sẽ cần thêm một phương thức riêng để có được tổng số kết quả. Đã hy vọng làm điều này tất cả trong một cuộc gọi.

Tôi không muốn mang lại tất cả các bản ghi để trình bày và sau đó trang ... có vẻ không hiệu quả.

+0

Nếu bạn đã trở về 'IEnumerable ' có lý do cụ thể nào đó bạn không chỉ sử dụng '.Count()' trên 'IEnumerable'? Bạn chỉ đang trình bày tập hợp con vào giao diện người dùng? Không nên giao diện người dùng chịu trách nhiệm phân trang? – AllenG

+0

IEnumerable bạn quay trở lại, nó có chứa tất cả các mục không? (cùng một số mục như số sẽ trả về) – Magnus

+0

@AllenG - Tôi đã thực hiện phân trang trong lớp dịch vụ, sau đó trả về một danh sách cho người dùng UI/Codebehind. Bằng cách này tôi có thể tránh bất kỳ vấn đề với đời sống Dbcontext của tôi. Ngoài ra, sau đó tôi sẽ không phải gửi tất cả các hồ sơ để kết thúc trước, sau đó làm các phân trang .. sẽ trực tiếp lấy các hồ sơ tôi cần trong truy vấn lớp dịch vụ. – jpshook

Trả lời

7

Bạn có thể làm một cái gì đó như thế này

public class Repository<TEntity> 
{ 
    public IEnumerable<TEntity> GetCollection(Expression<Func<TEntity, bool>> filter, 
     int pageSize, int pageIndex) 
    { 
     return YourDbSet.Where(filter).OrderBy(sortExpression).Skip(pageSize * pageIndex).Take(pageSize); 
    } 

    public int Count(Expression<Func<TEntity, bool>> filter) 
    { 
     return YourDbSet.Where(filter).Count(); 
    } 
} 

Sau đó, Bạn có thể viết một phương pháp mở rộng để sử dụng cả hai phương pháp

public static Pagination<TEntity> GetPagination<TEntity>(this Repository<TEntity> repository, 
    Expression<Func<TEntity, bool>> filter, int pageSize, int pageIndex) 
{ 
    var entities = repository.GetCollection(filter, pageSize, pageIndex); 
    var count = repository.Count(filter); 

    return new Pagination(entities, pageSize, pageIndex + 1, count); 
} 

Bằng cách này bạn có thể tái sử dụng GetCollectionCount phương pháp độc lập. Bạn có thể xây dựng điều kiện nơi động. Hãy xem answer

+0

Tôi vẫn đang học, vì vậy hãy cố gắng gắn bó với việc triển khai cụ thể cho đến khi tôi có được cái đầu của tôi xung quanh Generics. – jpshook

+0

@Developr vì bạn đang sử dụng IQueryable, bạn đã sử dụng Generics. các tham số chung được suy ra bởi trình biên dịch. vì vậy bạn không cần phải cung cấp cho họ – Eranga

+0

đây là liên kết đến một câu hỏi khác cho thấy kiến ​​trúc của tôi ... rất đơn giản và cụ thể: http://stackoverflow.com/questions/6416506/which-types-should-my-entity -framework-repository-and-service-layer-methods-retur – jpshook

1

Nếu Enumerable bạn quay trở lại chứa tất cả các mục, tôi sẽ thực hiện ToList() trên nó trước khi trở về nếu từ chức năng. (sau đó bạn có thể làm Count mà không mất phí) Nếu hàm trả về một tập hợp con của tổng số (sử dụng Skiptake), tôi sẽ thêm một hàm riêng biệt để nhận tổng số.