动态防爆pression使用LINQ。如何找到的厨房?厨房、动态、pression、LINQ

2023-09-03 02:33:53 作者:温歌酒中仙

我尝试做实现用户动态过滤器,用在选择一些属性,选择一些运营商也选择了值。

由于我没有找到还没有一个答案这个问题,我试图使用LINQ EX pressions 。照片 主要是我需要找出所有的房屋其主要房间有厨房的(任何桑斯,我知道)。

 使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用System.Linq.Ex pressions;
//使用System.Linq.Dynamic;

命名空间ConsoleApplication2
{
    类节目
    {
        静态无效的主要(字串[] args)
        {
            房间aRoom =新房间(){名称=客房};
            房间扫帚=新房间(){名称=B室};
            客房克鲁姆=新房间(){名称=C室};

            众议院的MyHouse =新房
            {
                客房=新的名单,其中,客房及GT;(新房间[] {} aRoom)
                MainRoom = aRoom
            };
            众议院yourHouse =新楼()
            {
                客房=新的名单,其中,客房及GT;(新房间[] {扫帚,克鲁姆}),
                MainRoom =扫帚
            };
            众议院donaldsHouse =新楼()
            {
                客房=新的名单,其中,客房及GT;(新房间[] {aRoom,扫帚,克鲁姆}),
                MainRoom = aRoom
            };

            VAR房子=新的名单,其中,房屋及GT;(新房[] {的MyHouse,yourHouse,donaldsHouse});

            // VAR厨房= houses.AsQueryable<家>(),其中(MainRoom.Type = RoomType.Kitchen)。
            //Console.WriteLine("kitchens数= {0},kitchens.Count());

            VAR houseParam =前pression.Parameter(typeof运算(楼),房子);
            VAR houseMainRoomParam =前pression.Property(houseParam,MainRoom);
            VAR houseMainRoomTypeParam =前pression.Property(houseMainRoomParam,类型);

            VAR roomTypeParam =前pression.Parameter(typeof运算(RoomType),roomType);

            VAR比较=前pression.Lambda(
                防爆pression.Equal(houseMainRoomTypeParam,
                防爆pression.Constant(厨房的typeof(RoomType)))
                );

            // ????????????????????????不工作
            VAR厨房= houses.AsQueryable(),其中(比较)。

            Console.WriteLine(厨房数= {0},kitchens.Count());
            Console.ReadKey();

        }
    }

    公共类之家
    {
        公共字符串的地址{获得;组; }
        公共双区{获得;组; }
        公共房间MainRoom {获得;组; }
        公开名单<房间>客房{获得;组; }
    }

    公共类房
    {
        公共双区{获得;组; }
        公共字符串名称{;组; }
        公共RoomType类型{获取;组; }
    }

    公共枚举RoomType
    {
        厨房,
        卧室,
        图书馆,
        办公室
    }
}
 

解决方案

  VAR的厨房,距离H =的房屋
               其中,h.MainRoom.Type == RoomType.Kitchen
               选择H;
 

但你必须设置在房间之前, RoomType 属性。

好吧,编辑:

所以你必须重新定义:

  VAR比较=前pression.Lambda< Func键<府,布尔>>(...
 
酒店厨房装修注意事项 酒店厨房装修步骤流程 酒店厨房装修怎么设计好用

然后,当你使用它:

  VAR厨房= houses.AsQueryable(),其中(comparison.Compile())。
 

编辑#2:

好了,在这里你去:

  VAR roomTypeParam =前pression.Parameter(typeof运算(RoomType),roomType);



// ????????????????????????不工作
VAR比较=前pression.Lambda< Func键<府,布尔>>(
    防爆pression.Equal(houseMainRoomTypeParam,
    防爆pression.Constant(Enum.Parse(typeof运算(RoomType),厨房)的typeof(RoomType))),houseParam);



// ????????????????????????不工作
VAR厨房= houses.AsQueryable(),其中(比较)。
 

编辑#3:为您的需求,我的想法现在。我举一个最后一个你:

在String类型声明扩展方法:

 内部静态对象prepare(此字符串值,类型类型)
{
    如果(type.IsEnum)
        返回Enum.Parse(类型,值);

    返回值;
}
 

然后用它在EX pression这样的:

 防爆pression.Constant(厨房。prepare(typeof运算(RoomType))的typeof(RoomType))
 

这是因为显然枚举的处理方式不同。该分机将离开该字符串不变为其他类型。缺点:您需要添加另一个 typeof运算()

I try do implement a user dynamic filter, where used selects some properties, selects some operators and selects also the values.

As I didn't find yet an answer to this question, I tried to use LINQ expressions. Mainly I need to identify all houses which main rooms are kitchens(any sens, I know).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
//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 });

            //var kitchens = houses.AsQueryable<House>().Where("MainRoom.Type = RoomType.Kitchen");
            //Console.WriteLine("kitchens count = {0}", kitchens.Count());

            var houseParam = Expression.Parameter(typeof(House), "house");
            var houseMainRoomParam = Expression.Property(houseParam, "MainRoom");
            var houseMainRoomTypeParam = Expression.Property(houseMainRoomParam, "Type");

            var roomTypeParam = Expression.Parameter(typeof(RoomType), "roomType");

            var comparison = Expression.Lambda(
                Expression.Equal(houseMainRoomTypeParam,
                Expression.Constant("Kitchen", typeof(RoomType)))
                );

            // ???????????????????????? DOES NOT WORK
            var kitchens = houses.AsQueryable().Where(comparison);

            Console.WriteLine("kitchens count = {0}", kitchens.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
    }
}

解决方案

var kitchens = from h in houses
               where h.MainRoom.Type == RoomType.Kitchen
               select h;

But you must set the RoomType property on the rooms before.

Ok, edit:

so you must redefine:

var comparison = Expression.Lambda<Func<House, bool>>(...

Then, when you use it:

var kitchens = houses.AsQueryable().Where(comparison.Compile());

Edit #2:

Ok, here you go:

var roomTypeParam = Expression.Parameter(typeof(RoomType), "roomType");



// ???????????????????????? DOES NOT WORK
var comparison = Expression.Lambda<Func<House, bool>>(
    Expression.Equal(houseMainRoomTypeParam,
    Expression.Constant(Enum.Parse(typeof(RoomType), "Kitchen"), typeof(RoomType))), houseParam);



// ???????????????????????? DOES NOT WORK
var kitchens = houses.AsQueryable().Where(comparison);

Edit #3: Of, for your needs, I am out of ideas for now. I give you one last one:

Declare an extension method on the String type:

internal static object Prepare(this string value, Type type)
{
    if (type.IsEnum)
        return Enum.Parse(type, value);

    return value;
}

Then use it in that expression like:

Expression.Constant("Kitchen".Prepare(typeof(RoomType)), typeof(RoomType))

That's because apparently enums are treated differently. That extension will leave the string unaltered for other types. Drawback: you have to add another typeof() there.