Порядок цепочек в общем сервисе на основе интерфейсов - PullRequest
0 голосов
/ 08 октября 2019

У меня есть несколько сущностей, которые реализуют интерфейс, например IHasOrder или IHasReference. У меня есть много и много сущностей, которые реализуют эти интерфейсы, и я хотел бы использовать их, чтобы избежать повторения кода.

Я пытаюсь реализовать универсальный сервис для предоставления общих методов управления сущностями.

public abstract class Service<TEntity> : Service, IService<TEntity>
        where TEntity : class, IEntity
{
}

Например, где-то в этой универсальной службе у меня есть метод, который извлекает все сущности из моей базы данных:

public virtual IEnumerable<TEntity> ReadAll()
{
    var query = GetQuery();
    query = Orders(query);

    return query.ToList();
}

Я хотел бы использовать свой интерфейс, чтобы всегда упорядочивать сущности, которые зависят от интерфейсовони реализуют. Например, для сущности Comment, которая реализует IHasOrder и IHasReference, метод ReadAll даст мне все Comments, упорядоченные по его свойству Order, а затем по его свойству Reference.

Содержимое Orders - это просто последовательность упорядочивания:

protected virtual IOrderedQueryable<TEntity> Orders(IQueryable<TEntity> query)
{
    var orderedQuery = query.OrderBy(null, null);

    orderedQuery = ThenBy(orderedQuery);
    orderedQuery = ThenByOrder(orderedQuery);
    orderedQuery = ThenByLabel(orderedQuery);
    orderedQuery = ThenByReference(orderedQuery);

    return orderedQuery;
}

А вот пример ThenBy... методов:

protected virtual IOrderedQueryable<T> ThenByOrder<T>(IOrderedQueryable<T> query)
{
    if (typeof(T).BasedOn<IHasOrder>())
    {
        return query.ThenBy(e => (e as IHasOrder).Order);
    }

    return query;
}

Все отлично работает в efcore, ноне в ef6. Я читал, что EF6 не знает, как управлять интерфейсами, но этот ответ заставил поверить, что для этого есть хитрость.

Если я попробую эту реализацию, объединение невозможно, так как.Cast<>() в конце превратит IOrderedQueryable<> в простой IQueryable, а следующий ThenBy(...) сгенерирует, так как IQueryable не имеет метода с именем ThenBy.

. управлять, чтобы сделать эту цепочку упорядочения на основе нескольких интерфейсов?

...