2016-11-29 4 views
1

Я написал метод расширения, который выражает выражение на основе условия, но когда условие является groupby, результатом является порядок by !!! что я не так?Динамический GroupBy с использованием выражения в .net-ядре

вот мой метод:

public static IQueryable<T> NewWhere<T, U>(this IQueryable<T> source, string prop, U value, string condition) 
    { 
    MethodInfo method; 
    Expression<Func<T, bool>> lambda = null; 
    Expression body = null; 

    string groupSelector = null; 
    var type = typeof(T); 
    var parameter = Expression.Parameter(type, "p"); 
    var property = Expression.Property(parameter, prop); 
    var constant = Expression.Constant(value, typeof(U)); 


    if (condition == "GreaterThan") 
    body = Expression.GreaterThan(property, constant); 
    else if (condition == "LessThan") 
    body = Expression.LessThan(property, constant); 
    else if (condition == "Equals") 
    body = Expression.Equal(property, constant); 

    //For implement sql like command we need them 
    else if (condition == "StartsWith") { 
    method = typeof(string).GetMethod("StartsWith", new[] { typeof(string) }); 
    body = Expression.Call(property, method, constant); 
    } 
    else if (condition == "EndsWith") 
    { 
    method = typeof(string).GetMethod("EndsWith", new[] { typeof(string) }); 
    body = Expression.Call(property, method, constant); 
    } 
    else if (condition == "Contains") 
    { 
    method = typeof(string).GetMethod("Contains", new[] { typeof(string) }); 
    body = Expression.Call(property, method, constant); 
    } 
    //For implement sql like command we need them 

    //group by only one field 
    if (condition == "GroupBy") 
    groupSelector = prop; 

    else 
    lambda = Expression.Lambda<Func<T, bool>>(body, new[] { parameter }); 

    //return the grouped by result or not grouped by 
    if (groupSelector != null) 
    { 
    var selectorExp = Expression.Lambda<Func<T, U>>(property, new ParameterExpression[] { parameter }); 
    source = source.GroupBy(selectorExp).SelectMany(g => g); 
    //source.GroupBy(e => e.GetType().GetProperty(groupSelector)).SelectMany(gr => gr); 
    } 
    else 
    source = source.Where(lambda); 

    return source; 
    } 

, но когда я запускаю mthod с условием GroupBy, результат:

SELECT [e].[Id], [e].[Year] 
FROM [org].[Data] AS [e] 
ORDER BY [e].[Year] 

я не знаю, почему его произошло?

ответ

2

TL; DR;: Entityity Framework использует запрос, потому что это самый эффективный способ получить то, что вы хотите.

Что такое Entity Framework, это перевести ваш запрос LINQ в SQL. Проверьте эту строку кода:

source = source.GroupBy(selectorExp).SelectMany(g => g); 

Вы группирование (вероятно, год), а затем вы выбираете все элементы группы. На самом деле вы не запрашиваете сгруппированный результирующий набор, вы ожидаете все позиции во всех группах в одном плоском результирующем наборе. Если EF сначала запросить группы, а затем запросить элементы группы, то сначала нужно будет выбрать все группы:

SELECT [e].[Year] 
FROM [org].[Data] AS [e] 
GROUP BY [e].[Year] 

Тогда бы получить элементы группы в одном запросе для каждой группы:

SELECT [e].[Id] 
FROM [org].[Data] AS [e] 
WHERE [e].[Year] = --Value 

Это, конечно, было бы очень неэффективно (особенно, так как вы расплющить список все равно с SelectMany), поэтому EF будет просто получить значение предписания группировки предиката и группировать их во время выполнения запроса (или в данном случае не группировать их на всех, поскольку вы запрашиваете плоский список). Как только запрос будет выполнен, EF может только начинаться в верхней части набора результатов и запускать новую группу каждый раз, когда встречается новый год.

Когда вы используете запросы EF, вы должны признать, что у вас не будет контроля над вашим SQL. Если вы этого хотите, создайте хранимые процедуры и запустите их из EF.

+0

я получил эту ERRO, является то, что причиной я использовал SelectMany: Не удается неявно преобразовать тип «System.Linq.IQueryable » до «System.Linq.IQueryable », я должен выбрать сгруппированных на всех. selectMany может объединить все данные вместе, правильно? – data

+0

Тип возврата вашего метода не совпадает с типом возвращаемого выражения 'GroupBy'. Вам придется соответствующим образом изменить тип возврата вашего метода. Это, скорее всего, не изменит ваш SQL-выход. – Sefe

+0

Как изменить тип возвращаемого типа groupby, потому что я не могу изменить тип возвращаемого метода, возвращаемый тип T, U для выражения lambda i, сделанного из свойства, точно до groupby – data

 Смежные вопросы

  • Нет связанных вопросов^_^