错误按字符串列名称分组(运行时列名称)

时间:2018-01-22 13:13:57

标签: c# linq reflection

我使用下面的q.GroupBy方法遇到错误。 它说:

  

无法隐式转换类型            System.Linq.IQueryable<System.Linq.IGrouping<TRet, TModel>>来            System.Linq.IQueryable<TModel>

上面是错误抛出

    public static IQueryable<TModel> GroupByDynamic<TModel>(this IQueryable<TModel> q, string name)
    {
        Type entityType = typeof(TModel);
        PropertyInfo p = entityType.GetProperty(name);
        MethodInfo m = typeof(QueryableHelper).GetMethod("GroupByProperty").MakeGenericMethod(entityType, p.PropertyType);          
        return (IQueryable<TModel>)m.Invoke(null, new object[] { q, p });
    }


    public static IQueryable<TModel> GroupByProperty<TModel, TRet>(IQueryable<TModel> q, PropertyInfo p)  
    {
        ParameterExpression pe = Expression.Parameter(typeof(TModel));
        Expression se = Expression.Convert(Expression.Property(pe, p), typeof(TRet));
        return q.GroupBy(Expression.Lambda<Func<TModel, TRet>>(se, pe));
    }

以下q.OrderBy语句无任何问题

   public static IQueryable<TModel> OrderByProperty<TModel, TRet>(IQueryable<TModel> q, PropertyInfo p)
    {
        ParameterExpression pe = Expression.Parameter(typeof(TModel));
        Expression se = Expression.Convert(Expression.Property(pe, p), typeof(TRet));
        return q.OrderBy(Expression.Lambda<Func<TModel, TRet>>(se, pe));
    }

1 个答案:

答案 0 :(得分:1)

您应该在分组后应用select子句并更改方法输出。

public static IQueryable<TRet> GroupByProperty<TModel, TRet>(IQueryable<TModel> q, PropertyInfo p)
{
    ParameterExpression pe = Expression.Parameter(typeof(TModel));
    Expression se = Expression.Convert(Expression.Property(pe, p), typeof(TRet));
    return q.GroupBy(Expression.Lambda<Func<TModel, TRet>>(se, pe)).Select(x => x.Key);
}

Func输入已经是TModel,您想要在此实体上应用组。所以我假设你想通过分组来选择Key。这就是更改方法返回类型的原因。

另一个选择是您可以将错误告诉的返回方法符号更改为IQueryable<IGrouping<TRet, TModel>>

public static IQueryable<IGrouping<TRet, TModel>> GroupByProperty<TModel, TRet>(IQueryable<TModel> q, PropertyInfo p)
{
    ParameterExpression pe = Expression.Parameter(typeof(TModel));
    Expression se = Expression.Convert(Expression.Property(pe, p), typeof(TRet));
    return q.GroupBy(Expression.Lambda<Func<TModel, TRet>>(se, pe));
}
public static IQueryable<IGrouping<dynamic, TModel>> GroupByDynamic<TModel>(this IQueryable<TModel> q, string name)
{
    Type entityType = typeof(TModel);
    PropertyInfo p = entityType.GetProperty(name);
    MethodInfo m = typeof(B).GetMethod("GroupByProperty").MakeGenericMethod(entityType, p.PropertyType);
    return (IQueryable<IGrouping<dynamic, TModel>>)m.Invoke(null, new object[] { q, p });
}