具有计数()>1的表达式树

4
我正在使用EF 6.1,我想使用以下SQL查询我的实体。
SELECT field, count(*) 
FROM entity
GROUP BY field
HAVING COUNT(*) > 1

这里的fieldentity都是变量。如果两者在编译时都已知,我可以使用Context.Set<Entity>().GroupBy(e => e.Field).Where(f => f.Count() > 1).Select(f => f.Key)来解决。 编辑:忘记提到field始终是字符串类型。
我认为使用表达式树是可能的,但我对此不太熟悉,学习曲线有点陡峭。
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();
        }

有人能指导我走向正确的方向吗?

编辑

澄清一下;我正在寻找像这样的东西(以下内容将检查TSource类型实体中的field是否为空)。

public Func<TSource, bool> IsNull<TSource>(string field)
        {
            var parameter = Expression.Parameter(typeof(TSource), "p");
            var property = Expression.Property(parameter, field);
            return Expression.Lambda<Func<TSource, bool>>(
                Expression.Equal(property, Expression.Constant(null, property.Type)), new[] { parameter }).Compile();
        }

我可以这样使用它
context.Set<TEntity>()
                    .Where(e => !e.AMT_ValidationStatus.Equals(ValidationStatus.FAILED.ToString()))
                    .Where(IsNull<TEntity>(f.Name))

1
这个有用吗?https://dev59.com/4XI95IYBdhLWcg3w8y2N - Corak
不,它不能。这只在编译时知道实体类型和字段名才能工作。我想在运行时已知这些信息的情况下做同样的事情。 - Hintham
EF的整个理念在于进行编译时类型检查的操作。我认为如果它不过类型检查,那么就没有任何方法可以实现这一点 - 例如,使用属性名称作为字符串。与此相关,也需要回答以下问题:您打算如何使用CountMultiple函数? - Martijn
这正是我使用表达式树而不是魔术字符串试图避免的。 - Hintham
避免使用魔术字符串,可以使用由魔术字符串构建的表达式树。 - Ivan Stoev
1个回答

0

好的,我搞定了

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);
        }

这可以被用作(f.NameTEntity 中属性的名称)

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接