C# 具有count()的表达式树>;1.

C# 具有count()的表达式树>;1.,c#,entity-framework,linq,C#,Entity Framework,Linq,我使用的是EF6.1,我想使用以下SQL查询我的实体 SELECT field, count(*) FROM entity GROUP BY field HAVING COUNT(*) > 1 这里,字段和实体都是可变的。如果在编译时两者都已知,我可以使用Context.Set().GroupBy(e=>e.Field).其中(f=>f.Count()>1).选择(f=>f.Key) 编辑 忘了提到字段总是字符串类型 我认为使用表达式树是可能的,但我不太熟悉,学习曲线有点陡峭 publ

我使用的是EF6.1,我想使用以下SQL查询我的实体

SELECT field, count(*) 
FROM entity
GROUP BY field
HAVING COUNT(*) > 1
这里,
字段
实体
都是可变的。如果在编译时两者都已知,我可以使用
Context.Set().GroupBy(e=>e.Field).其中(f=>f.Count()>1).选择(f=>f.Key)

编辑 忘了提到
字段
总是字符串类型

我认为使用表达式树是可能的,但我不太熟悉,学习曲线有点陡峭

public Func<TSource, what's the return type?> CountMultiple<TSource>(string field)
        {
            var parameter = Expression.Parameter(typeof(TSource), "p");
            var property = Expression.Property(parameter, field);
.
Some more Expression magic goes here                
.

            return Expression.Lambda<Func<TSource, the return type>>(?, ?).Compile();
        }
然后我可以如下使用它

context.Set<TEntity>()
                    .Where(e => !e.AMT_ValidationStatus.Equals(ValidationStatus.FAILED.ToString()))
                    .Where(IsNull<TEntity>(f.Name))
context.Set()
.Where(e=>!e.AMT\u ValidationStatus.Equals(ValidationStatus.FAILED.ToString())
.其中(IsNull(f.Name))
好的,算了

public static IQueryable<IGrouping<string, TSource>> Grouper<TSource>(IQueryable<TSource> source, string field)
        {
            var parameter = Expression.Parameter(typeof(TSource), "x");
            var property = Expression.Property(parameter, field);
            var grouper = Expression.Lambda<Func<TSource, string>>(property, parameter);

            return source.GroupBy(grouper);
        }

这有用吗?不,它没有,这只有在编译时知道实体类型和字段名时才有效。我想在运行时知道它们的地方也能做到这一点。EF的全部思想是在编译时进行类型检查。我认为当它不进行类型检查时,没有任何方法可以做到这一点——例如,使用属性名作为字符串。相关并且需要回答问题:你打算如何使用CountMultiple函数?这正是我试图通过使用表达式树而不是魔术字符串来避免的。嗯,通过使用用魔术字符串构建的表达式树来避免魔术字符串。
public static IQueryable<IGrouping<string, TSource>> Grouper<TSource>(IQueryable<TSource> source, string field)
        {
            var parameter = Expression.Parameter(typeof(TSource), "x");
            var property = Expression.Property(parameter, field);
            var grouper = Expression.Lambda<Func<TSource, string>>(property, parameter);

            return source.GroupBy(grouper);
        }
Grouper(context.Set<TEntity>(), f.Name)
                                .Where(field => field.Count() > 1)
                                .Select(s => new { Key = s.Key, Count = s.ToList().Count })