Expression.Constant отбрасывает существующие условия WHERE применительно к IQueryable <T> - PullRequest
0 голосов
/ 09 июля 2019

Контекст

У меня есть метод расширения IQueryable GetAllGroupedBy, который должен решить проблему наибольшего числа групп в MySQL через EF Core.

В основном это конструирует этот тип

public struct OrderedGroupItem<TModel, TKey>
{
    public TKey GroupKey { get; set; }
    public int OrderKey { get; set; }
    public TModel Value { get; set; }
}

внутренне путем подсчета для каждого элемента в таблице, сколько элементов находится ниже этого элемента в любом заданном порядке.

Код длиной 100 строк, его можно найти здесь .

Задача

Когда в методе расширения передается запрос IQueryable<T>, отладчик показывает:

value(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[Persistence.Models.Project])
        .Where(...)

потому что метод расширений вызывается так:

query.Where(...).GetAllGroupedBy(...);

, поэтому переданный query правильно сохраняет часть Where(...), предшествующую вызову GetAllGroupedBy.

Но когда я помещаю его в выражение через Expression.Constant(query), получается выражение:

{
    new OrderedGroupItem`2() 
    {
        GroupKey = Invoke(x => x.GroupKey, x), 
        OrderKey = value(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[Type])
            .Where(y => 
                (Invoke(x => x.GroupKey, x) 
                    == Invoke(x => x.GroupKey, y))
            )
            .Where(y => 
                Invoke((x, y) => 
                    (
                        (Compare(x.OrderValue, y.OrderValue) < 0) 
                        OrElse (
                            (Compare(x.OrderValue, y.OrderValue) == 0) 
                            AndAlso (x.Id < y.Id)
                        )
                    ), 
                    x, 
                    y
                )
            ).Count(), 
        Value = x
    }
}

и переведенный SQL не повторяет оригинальные .Where(...) фильтры.

Вопрос

Почему Expression.Constant(queryable) удаляет условия .Where(...), сохраненные в запросе? Что я делаю не так?

1 Ответ

1 голос
/ 09 июля 2019

Вместо:

Expression.Constant(query)

вы должны использовать:

query.Expression
...