2009-06-12 56 views
17

Tôi thích sử dụng lại các biểu thức vì lý do DRY, nhưng làm cách nào để sử dụng lại các biểu thức trong câu lệnh LINQ?Làm cách nào để tôi có thể sử dụng lại các biểu thức trong các câu lệnh LINQ?

ví dụ:

Tôi có

public static class MyExpressions { 
    public static Expression<Func<Product,bool>> IsAGoodProduct() { 
     return (p) => p.Quality>3; 
    } 
} 

Và muốn sử dụng trong báo cáo LINQ, vì vậy

var goodProds = from p in dataContext.Products 
        where ????? // how do I use IsAGoodProduct here? 
        select p; 

Chắc chắn, tôi có thể sử dụng chức năng IQueryableExtension.Where, nhưng điều đó sẽ làm cho gia nhập và các chức năng khác alot xấu hơn cho các truy vấn phức tạp hơn.

Điều này có thể hay là hạn chế của LINQ?

Trả lời

21

Nếu bạn di chuyển từ đường cú pháp LINQ có thể:

var goodProds = dataContext.Products.Where(MyExpressions.IsAGoodProduct()); 

Nếu không có nó, nó không phải là có thể.

Không có gì ngăn bạn trộn hai kiểu để tạo một truy vấn đơn lẻ.

Ví dụ:

var goodProds = from p in dataContext.Products 
             .Where(MyExpressions.IsAGoodProduct()) 
        group p by p.Category into g 
        select new {Category = g.Key, ProductCount = g.Group.Count()}; 
+1

@Gary - hy vọng bạn không nhớ rằng tôi đã thêm một ví dụ để làm cho nó rõ ràng hơn. – tvanfosson

+0

Không, điều đó tuyệt vời :) –

+0

Điều gì về việc sử dụng: "nơi IsAGoodProduct(). Biên dịch(). Gọi()" – Razzie

1

Bằng cách này, tôi đã đi qua useful article này sẽ giải thích cách bạn có thể tạo động LINQ truy vấn có chức năng tham khảo bọc như Expressions sử dụng một tùy chỉnh phương pháp khuyến nông ToExpandable(). Các giải pháp được cung cấp có thể được sử dụng trong các phần khác nhau của một truy vấn LINQ tất cả trong khi bảo quản việc sử dụng comprehension syntax thay vì sử dụng cú pháp lambda.

2

Chúng tôi đã có cùng một vấn đề. Nó không được hỗ trợ ra khỏi hộp và nó là một vấn đề lớn cho các ứng dụng LOB. Tôi đã kết thúc viết một bài viết mã dự án về tái sử dụng biểu thức LINQ, bao gồm một tiện ích rất nhỏ gọi là LinqExpressionPrjection cho phép tái sử dụng trong các phép chiếu (bao gồm cả các loại ẩn danh).

Tìm bài viết here.

Bạn có thể nhận được lắp ráp cho việc tái sử dụng chiếu dưới dạng nuget package và nguồn là trên CodePlex.

Đã qua một thời gian kể từ khi bài đăng của bạn. Tôi hy vọng nó vẫn hữu ích cho bạn. Nếu không, có thể cho những người khác đọc chủ đề này.

3

Tôi đã gặp vấn đề tương tự và muốn duy trì khả năng sử dụng các phương pháp mở rộng trong cú pháp truy vấn (như với các chức năng được hỗ trợ thông thường ...). Một giải pháp có thể là this library.

Bạn chỉ cần triển khai phương pháp để sử dụng lại hai lần, một lần để sử dụng chung và một lần cho các truy vấn.

public static class MyFunctions { 
    [InjectLambda] 
    public static bool IsAGoodProduct(Product product) { 
     return product.Quality>3; 
    } 
    public static Expression<Func<Product,bool>> IsAGoodProduct() { 
     return (p) => p.Quality>3; 
    } 
} 

Truy vấn thực tế có thể trông như mong đợi.

var goodProds = from p in dataContext.Products.ToInjectable() 
       where p.IsAGoodProduct() 
       select p; 

Các ToInjectable gọi tạo ra một proxy nhẹ, thay thế các cuộc gọi IsAGoodProduct phương pháp (nếu đánh dấu cho phù hợp) với các biểu thức lambda mong muốn.Do đó, bạn có thể sử dụng các phương thức mở rộng ở bất kỳ đâu trong các truy vấn - các phương thức tham số cũng hoạt động tốt.

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