Как использовать Enums с Dynamic Linq? - PullRequest
8 голосов
/ 16 августа 2011

Я хотел бы использовать перечисления в моих динамических запросах LINQ.

Возможно ли это, и если да, то как?

Рассмотрим приведенный ниже код:

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
    }
}

Ответы [ 5 ]

17 голосов
/ 21 июня 2012

Я столкнулся с той же проблемой и попробовал помеченный ответ, указанный @Steve Wilkes, но у меня это не сработало !! Затем я обнаружил, что динамический LINQ содержит документацию HTML в том же пакете, в котором упоминается, что Enums можно указывать как строковые литералы.

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

Который работал для меня.

4 голосов
/ 16 августа 2011

Это работает:

houses.AsQueryable<House>()
    .Where("MainRoom.Type = ConsoleApplication2.RoomType.Kitchen")
1 голос
/ 07 ноября 2013

вдобавок еще один вариант использования параметра

var aRoomsHouses = houses.AsQueryable<House>().Where("MainRoom.Type = @0",RoomType.Kitchen);
1 голос
/ 16 августа 2011

Это должно работать

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

Зачем вам нужен динамический linq в этом случае? Какой выход вы ожидаете

По моему предпочтению, следует избегать использования склонной к ошибкам строки. Если имя вашего класса или свойства изменилось, вы не сможете найти ошибку, пока не встретите ее.

Скорее используйте выражение

    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);

Вы можете создать выражение, в котором вы решите, какой строковый фильтр использовать. Лучше создать статический класс или оператор switch, который дает вам другой тип выражения, который вы можете использовать в качестве аргумента where.

0 голосов
/ 22 марта 2013

Чтобы добавить новый тип Enum к динамическому linq, вы должны добавить следующий код:

typeof(Enum),
typeof(T)

T : Enum type

в предопределенных типах динамиков. Это работает для меня;

...