2012-06-16 34 views
6

Tôi đã tạo một phương thức tiện ích mở rộng trên loại IQueryable, có một nhóm nhỏ các thực thể và lọc chúng theo một số criterrions. Vấn đề của tôi là tôi không thể trả về một biểu thức Union làm bằng các biến, mà không phải tất cả đều được khởi tạo trước. Các giá trị rỗng, như là các giá trị, không hợp lệ.Tôi nên khởi tạo các biến IQueryable như thế nào trước khi sử dụng biểu thức Union?

public static IQueryable<Person> FilterHairColors(this IQueryable<Person> subQuery, string[] hairColors) 
    { 
     IQueryable<Person> q1 = null; 
     IQueryable<Person> q2 = null; 
     IQueryable<Person> q3 = null; 
     IQueryable<Person> q4 = null; 

     foreach (var value in hairColors) 
     { 
      switch (value) 
      { 
       case "1": 
        q1 = subQuery.Where(p => p.HairColor_bright == true); 
        break; 
       case "2": 
        q2 = subQuery.Where(p => p.HairColor_brown == true); 
        break; 
       case "3": 
        q3 = subQuery.Where(p => p.HairColor_dark == true); 
        break; 
       case "4": 
        q4 = subQuery.Where(p => p.HairColor_red == true); 
        break; 
      } 
     } 
     return q1.AsQueryable().Union(q2.AsQueryable()).Union(q3.AsQueryable()).Union(q4.AsQueryable()); 
    } 

Các khối mã được trình bày là một phần của nhiều hơn, và mỗi tạo ra một tập hợp con của dữ liệu, chuyển tải đến một phương pháp lọc tiếp theo cách này:

results = persons.FilterGender(vm.gender).FilterAge(vm.age).FilterHeight(vm.height)...... 

Trả lời

3

Đừng gọi Liên minh khi một trong những đối số là null.

"Truy vấn vô giá trị" có ý nghĩa gì đối với bạn? Nếu nó có nghĩa là "không có hàng" thì chỉ cần không liên kết nó. Nếu nó có nghĩa là "tất cả các hàng", bạn không cần phải kết hợp vì bạn chỉ có thể truy vấn cơ bản, chưa được lọc.

Như thế này:

var result = new [] { q1, q2, q3, q4, }.Where(query => query != null).Aggregate(Queryable.Union); 

này được sử dụng LINQ-to-Đối tượng để xây dựng một truy vấn LINQ-to-SQL.

Một phiên bản mới:

var result = dataContext.Persons.Where(_ => false); 
if(q1 != null) result = result.Union(q1); 
if(q2 != null) result = result.Union(q2); 
if(q3 != null) result = result.Union(q3); 
if(q4 != null) result = result.Union(q4); 

Các SQL Server truy vấn tối ưu hóa sẽ loại bỏ các truy vấn giả đầu tiên để nó không có chi phí thời gian chạy ở tất cả.

+0

Sau đó, làm cách nào để điều kiện Liên minh hoạt động với các biến không phải là rỗng? –

+0

Tôi đã thêm một đề xuất. – usr

+0

Cảm ơn 'usr'. Bạn có thể nghĩ cách đơn giản hơn, trực quan hơn để truy cập vào vấn đề của tôi không? –

1
public static IQueryable<Person> FilterHairColors(this IQueryable<Person> subQuery, string[] hairColors) 
{ 
    var result = new Person[] { }.AsQueryable(); 
    var contains = new Dictionary<string, Expression<Func<Person, bool>>>(); 

    contains.Add("1", p => p.HairColor_bright); 
    contains.Add("2", p => p.HairColor_brown); 
    contains.Add("3", p => p.HairColor_dark); 
    contains.Add("4", p => p.HairColor_red); 

    foreach (var color in hairColors) 
    { 
     result = subQuery.Where(contains[color]).Union(result); 
    } 

    return result; 
} 
+0

Tôi đã thử điều đó, và nó đi kèm với lỗi này: "Phương pháp này hỗ trợ cơ sở hạ tầng LINQ to Entity và không có ý định được sử dụng trực tiếp từ mã của bạn". xem chủ đề regading: http://social.msdn.microsoft.com/Forums/is/adodotnetentityframework/thread/3962b925-fe1e-4b96-ade3-5cb3b4be4511 –

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