2011-08-16 35 views
6

Tôi muốn sử dụng các liệt kê trong các truy vấn LINQ động của mình.Làm thế nào để sử dụng Enums với Dynamic LINQ?

Có thể, và nếu như thế nào?

xem xét mã dưới đây:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Linq.Dynamic; 

namespace ConsoleApplication2 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Room aRoom = new Room() { Name = "a Room" }; 
      Room bRoom = new Room() { Name = "b Room" }; 
      Room cRoom = new Room() { Name = "c Room" }; 

      House myHouse = new House 
      { 
       Rooms = new List<Room>(new Room[] { aRoom }), 
       MainRoom = aRoom 
      }; 
      House yourHouse = new House() 
      { 
       Rooms = new List<Room>(new Room[] { bRoom, cRoom }), 
       MainRoom = bRoom 
      }; 
      House donaldsHouse = new House() 
      { 
       Rooms = new List<Room>(new Room[] { aRoom, bRoom, cRoom }), 
       MainRoom = aRoom 
      }; 

      var houses = new List<House>(new House[] { myHouse, yourHouse, donaldsHouse }); 

      // MainRoom.Name = \"a Room\" and Rooms.Count = 3 or 
      // ????????????????????????? 
      var aRoomsHouses = houses.AsQueryable<House>().Where("MainRoom.Type = \"RoomType.Kitchen\""); 

      Console.WriteLine("aRoomsHouses count = {0}", aRoomsHouses.Count()); 
      Console.ReadKey(); 
     } 
    } 

    public class House 
    { 
     public string Address { get; set; } 
     public double Area { get; set; } 
     public Room MainRoom { get; set; } 
     public List<Room> Rooms { get; set; } 
    } 

    public class Room 
    { 
     public double Area { get; set; } 
     public string Name { get; set; } 
     public RoomType Type { get; set; } 
    } 

    public enum RoomType 
    { 
     Kitchen, 
     Bedroom, 
     Library, 
     Office 
    } 
} 
+0

Bạn cần phải sử dụng động-LINQ. Nó có thể được thực hiện với tiêu chuẩn linq –

+0

@Dean:) Tôi cần LINQ động. – serhio

Trả lời

4

này hoạt động:

houses.AsQueryable<House>() 
    .Where("MainRoom.Type = ConsoleApplication2.RoomType.Kitchen") 
+0

đầu tiên không hoạt động. 'int' không được tìm thấy là thuộc tính 'House' ..., thứ hai không hoạt động vì cùng lý do ..., và nói chung, bạn không thể sử dụng "==", nhưng "=". Tôi sợ rằng bạn chưa thử nghiệm truy vấn của mình ... – serhio

+0

Xin lỗi - bạn đã hoàn toàn đúng - tôi đã viết cả hai tùy chọn từ bộ nhớ mờ ... Tôi vừa thử nghiệm cả hai và đầu tiên là không có, nhưng thứ hai với một dấu bằng chỉ hoạt động tốt, vì vậy tôi đã cập nhật câu trả lời của tôi để chỉ bao gồm một. –

+0

bạn có lý do. Truy vấn của bạn hoạt động, vì vậy, có lẽ đây là một câu trả lời hay. Tuy nhiên, tôi đã đăng trên một khác :), do đó, cũng tự hỏi làm thế nào để làm cho nó hoạt động http://stackoverflow.com/q/7077056/185593 – serhio

1

này nên làm việc

houses.AsQueryable<House>().Where(rs=>rs.MainRoom.Type == RoomType.Kitchen); 

Tại sao bạn cần LINQ năng động trong trường hợp này? Những gì bạn mong đợi sản lượng

Để ưu tiên của tôi, sử dụng chuỗi dễ bị lỗi nên tránh. Nếu tên lớp hoặc tên thuộc tính của bạn thay đổi, bạn sẽ không thể tìm thấy lỗi cho đến khi bạn gặp phải lỗi đó.

Thay sử dụng biểu

Expression<Func<House, bool>> 
     filter = (p) => p.MainRoom.Type == RoomType.Kitchen; 
     filter = (p) => p.MainRoom.Area > 200; 
     filter = (p) => p.Rooms.Sum(rs => rs.Area) > 500; 
     filter = (p) => p.Address.Contains("abc"); 
     filter = (p) => p.Area > 200; 
     ... 
    var aRoomsHouses = houses.AsQueryable<House>().Where(filter); 

Bạn có thể tạo các biểu hiện nơi bạn quyết định lọc chuỗi được sử dụng. Tốt hơn nên tạo một lớp tĩnh hoặc có thể là câu lệnh chuyển đổi cung cấp cho bạn loại biểu thức khác nhau mà bạn có thể sử dụng làm đối số nơi.

+0

Liên kết tĩnh không có cách nào ... Tôi cần LINQ động, vì tôi xây dựng động bộ lọc dựa trên đặc tả bộ lọc người dùng. – serhio

+0

Tôi thấy không có lý do bạn không thể làm các loại truy vấn bạn đang làm với LINQ tiêu chuẩn, từ đầu vào của người dùng. –

+0

@Andrew, nếu người dùng chọn từ combo "Kitchen", tôi cần phải biến nó thành "RoomType.Kitchen", và có lẽ nó không chọn loại phòng, nhưng diện tích phòng ít hơn 30m2 nói ... vì vậy tôi cần truy vấn * động * – serhio

16

tôi gặp phải vấn đề này cùng và cố gắng câu trả lời rõ rệt theo quy định của @Steve Wilkes nhưng nó không làm việc cho tôi !! Sau đó, tôi phát hiện ra rằng LINQ động có một tài liệu HTML trong cùng một gói mà đề cập rằng Enums có thể được chỉ định như String Literals.

houses.AsQueryable<House>().Where("MainRoom.Type = \"Kitchen\"") 

Làm việc cho tôi.

+2

Cảm ơn! Không có gì ở trên làm việc nhưng sử dụng tên giá trị enum như là tác phẩm văn học tuyệt vời. –

+0

Điều này làm việc hoàn hảo với tôi, mẹo tuyệt vời –

+1

Đây phải là câu trả lời được chấp nhận – victorvartan

-1

Để thêm một kiểu Enum mới để LINQ năng động, bạn phải thêm đoạn mã sau:

typeof(Enum), 
typeof(T) 

T : Enum type 

trong predefinedTypes năng động Đó là công việc đối với tôi;

1

ngoài thêm một tham số sử dụng biến thể

var aRoomsHouses = houses.AsQueryable<House>().Where("MainRoom.Type = @0",RoomType.Kitchen); 
Các vấn đề liên quan