2016-07-15 1 views
4

Я использую EF 6.1, и я хотел бы запросить свои объекты, используя следующий SQLВыражение дерево за то, что количество()> 1

SELECT field, count(*) 
FROM entity 
GROUP BY field 
HAVING COUNT(*) > 1 

Вот как field и entity изменчивы. Если оба были известны во время компиляции я мог бы использовать Context.Set<Entity>().GroupBy(e => e.Field).Where(f => f.Count() > 1).Select(f => f.Key)

EDIT Забыл упомянуть, что 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(); 
     } 

Может ли кто-нибудь указать мне в правильном направлении?

EDIT

Для уточнения; Я ищу что-то вроде этого (ниже будет проверять field в сущности типа TSource для нуль)

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

Помогло ли это? http://stackoverflow.com/questions/2078736/linq-with-group-by-having-count – Corak

+0

Нет, это не так, это работает, только если вы знаете тип сущности и имя поля во время компиляции. Я хочу иметь возможность делать то же самое, где они известны во время выполнения. – Hintham

+0

Вся идея EF заключается в том, что вы делаете вещи, которые проверяются typecheck во время компиляции. Я не думаю, что есть способ сделать это, когда это не typecheck - например, используя имя свойства в виде строки. Связано и необходимо ответить на вопрос: как вы планируете использовать функцию CountMultiple? – Martijn

ответ

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.Name это имя свойства в TEntity)

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