每个属性的GroupBy Lamda表达式生成器

时间:2019-08-05 09:59:08

标签: c# linq expression

我想用列表中的项填充ComboBox的项源,具体取决于从T中选择了哪个属性。

该语句应类似于: foreach属性是一个字符串,   选择属性的值,使其与众不同。

    public Dictionary<string, List<string>> CreateSuggestionsLists<T>(List<T> data)
    {
        var queryableData = data.AsQueryable();
        var paramExp = Expression.Parameter(typeof(T), "left");
        foreach (var pi in typeof(T).GetProperties().Where(p => p.PropertyType == typeof(string)))
        {
            var callExpr = Expression.MakeMemberAccess(paramExp, pi);
            var lambdaExpr = Expression.Lambda(callExpr) ;
            // From here on it goes wrong!!!
            var comleteExpr = lambdaExpr as Expression<Func<T, bool>>;
            var compiledExpr = comleteExpr.Compile();

            var res = data.Select(compiledExpr).Distinct().ToList();
            // add to results ...
        }

        return null;
    }

问题似乎在于从lambda表达式进行强制转换以准备进行编译。

谢谢您的帮助。

2 个答案:

答案 0 :(得分:0)

首先,您需要提供paramExp到lambda。其次,有Lamda方法的通用版本,它更易于使用。最后,使用IQueryable时无需编译表达式。您创建了queryableData变量,但没有使用它。

这是代码:

    public Dictionary<string, List<string>> CreateSuggestionsLists<T>(List<T> data)
    {
        var queryableData = data.AsQueryable();
        var paramExp = Expression.Parameter(typeof(T), "left");
        foreach (var pi in typeof(T).GetProperties().Where(p => p.PropertyType == typeof(string)))
        {
            var callExpr = Expression.MakeMemberAccess(paramExp, pi);
            var lambdaExpr = Expression.Lambda<Func<T, bool>>(callExpr, paramExp);

            var res = queryableData.Select(lambdaExpr).Distinct().ToList();
            // add to results ...
        }

        return null;
    }

答案 1 :(得分:-1)

我认为您应该检查转换结果是否不为null:

          public Dictionary<string, List<string>> CreateSuggestionsLists<T>(List<T> data)
    {
        IQueryable<T> queryableData = data.AsQueryable();
        ParameterExpression paramExp = Expression.Parameter(typeof(T), "left");

        foreach (PropertyInfo pi in typeof(T).GetProperties().Where(p => p.PropertyType == typeof(string)))
        {
            MemberExpression callExpr = Expression.MakeMemberAccess(paramExp, pi);
            LambdaExpression lambdaExpr = Expression.Lambda(callExpr);
            // From here on it goes wrong!!!
            if (!(lambdaExpr is Expression<Func<T, bool>> comleteExpr)) continue;

            Func<T, bool> compiledExpr =  comleteExpr.Compile();

            List<bool> res = data.Select(compiledExpr).Distinct().ToList();

            // add to results ...
        }

        return null;
    }