代码之家  ›  专栏  ›  技术社区  ›  Mrinal Kamboj

如何为List<string>和Expression<Func<T,bool>>创建MemberExpression

  •  3
  • Mrinal Kamboj  · 技术社区  · 8 年前

    Expression<Func<T,bool>> ,这有助于提供 Func<T,bool> ,对于列表过滤,现在我需要创建一个 MemberExpression

     MemberExpression memberExpressionColumn = Expression.Property(parameterType,"X");
    

    在哪里? X 属性的名称是用来过滤的,所以当我在 List<Person> ,更换方便 十 有财产 Name , List<string> 作为源,那么如何创建 成员表达式 ,这将导致异常

    void Main()
    {
        List<Person> personList = new List<Person>()
            {
                new Person{ Name = "Shekhar", Age = 31},
                new Person{ Name = "Sandip", Age = 32},
                new Person{ Name = "Pramod", Age = 32},
                new Person{ Name = "Kunal", Age = 33}
            };
    
    
        var personNameList = personList.Select(p => p.Name).ToList();
    
        var personNameHashset = new HashSet<string>(personNameList);
    
        var nameList = new List<string>() { "Kunal", "Pramod", "Mrinal" };
    
        var finalExpression = personNameHashset.EqualExpression<string>("Name");
    
        var finalFunc = finalExpression.Compile();
    
        var result = nameList.Where(finalFunc);
    
        result.Dump();
    }
    
    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }
    
    public static class ExpressionTreesExtension
    {
        public static Expression<Func<T, bool>> EqualExpression<T>(this HashSet<string> nameHashSet, string columnName)
        {
            var expressionList = new List<Expression>();
    
            ParameterExpression parameterType = Expression.Parameter(typeof(T), "obj");
    
            // Exception Here - How to create MemberExpression for primitive type list List<string>
    
            MemberExpression memberExpressionColumn = Expression.Property(parameterType,columnName);
    
            var containsMethodInfo = typeof(StringListExtensions).GetMethod("Contains", new[] { typeof(string), typeof(HashSet<string>) });
    
            ConstantExpression constant = Expression.Constant(nameHashSet, typeof(HashSet<string>));
    
            var resultExpression = Expression.Call(null, containsMethodInfo, memberExpressionColumn, constant);
    
            return Expression.Lambda<Func<T, bool>>(resultExpression, parameterType);
        }
    }
    
    public static class StringListExtensions
    {
        /// <summary>
        /// String Extension - Contains (Substring)
        /// </summary>
        /// <param name="source"></param>
        /// <param name="subString"></param>
        /// <returns></returns>
        public static bool Contains(this string name, HashSet<string> nameHashSet)
        {
            return nameHashSet.Contains(name);
        }
    }
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   AlbertK    8 年前

    据我所知,你需要得到这样的结果:

    var result = nameList.Where(obj => personNameHashset.Contains(obj));
    

    Name 属性 memberExpressionColumn 你可以打电话给我 containsMethodInfo 具有 ParameterExpression parameterType Expression<Func<T, bool>> 这样地

    public static Expression<Func<T, bool>> EqualExpression<T>(this HashSet<string> nameHashSet)
    {
        ParameterExpression parameterType = Expression.Parameter(typeof(T), "obj");
        var containsMethodInfo = typeof(StringListExtensions).GetMethod("Contains", new[] { typeof(string), typeof(HashSet<string>) });
        ConstantExpression constant = Expression.Constant(nameHashSet, typeof(HashSet<string>));
        var resultExpression = Expression.Call(null, containsMethodInfo, parameterType, constant);
        return Expression.Lambda<Func<T, bool>>(resultExpression, parameterType);
    }
    

    并称之为:

    var finalExpression = personNameHashset.EqualExpression<string>();
    var finalFunc = finalExpression.Compile();
    var result = nameList.Where(finalFunc);