Как внедрить ThenInclude в пользовательскую спецификацию EF Core? - PullRequest
1 голос
/ 19 февраля 2020

EF Core 3.1 Я видел пример спецификации и хочу реализовать шаблон ThenInclude.

public static class QuerySpecificationExtensions
{
    public static IQueryable<T> Specify<T>(this IQueryable<T> query, ISpecification<T> spec) where T : class
    {
        // fetch a Queryable that includes all expression-based includes
        var queryableResultWithIncludes = spec.Includes
            .Aggregate(query,
                (current, include) => current.Include(include));

        // modify the IQueryable to include any string-based include statements
        var secondaryResult = spec.IncludeStrings
            .Aggregate(queryableResultWithIncludes,
                (current, include) => current.Include(include));

        // return the result of the query using the specification's criteria expression
        return secondaryResult.Where(spec.Criteria);
    }
}

Я могу добавить это в строку, например "User.UserRole.Role", но я хочу реализовать объект. Может быть, там это не возможно?

1 Ответ

2 голосов
/ 19 февраля 2020

Includes член вышеупомянутого ISpecification<T> объявлен как

List<Expression<Func<T, object>>> Includes { get; }

Проблема в том, что цепочка EF Core Include / ThenInclude не может быть представлена ​​с Expression<Func<T, object>>. Этот шаблон использовался в EF6, который поддерживал специальный синтаксис (Select) внутри выражения include для разрешения элемента коллекции. Но EF Core не поддерживает это из коробки.

Самый простой и естественный способ подключить шаблон EF Core - это изменить определение следующим образом:

List<Func<IQueryable<T>, IIncludableQueryable<T, object>>> Includes { get; }

Добавление образца для сущность, имеющая свойство User, имеющее коллекцию UserRoles, имеющую свойство Role, будет выглядеть следующим образом:

Includes.Add(q => q.Include(e => e.User).ThenInclude(e => e.UserRoles).ThenInclude(e => e.Role));

И соответствующая часть реализации метода Specify будет иметь вид:

var queryableResultWithIncludes = spec.Includes
    .Aggregate(query,
        (current, include) => include(current));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...