Как перенести метод расширения Entity Framework Включить в универсальный IQueryable <TSource> - PullRequest
5 голосов
/ 22 июля 2011

Вот в чем дело.

У меня есть интерфейс, и я бы добавил метод расширения Include, принадлежащий библиотеке EntityFramework , в мой слой IRepository, который неНужно знать о EntityFramework .

public interface IRepository<TEntity>
{
    IQueryable<TEntity> Entities { get; }

    TEntity GetById(long id);
    TEntity Insert(TEntity entity);
    void Update(TEntity entity);
    void Delete(TEntity entity);
    void Delete(long id);
}

Итак, у меня есть метод расширения:

public static class IncludeExtension 
{
    static IQueryable<TEntity> Include<TEntity>(this IQueryable<TEntity> query, 
        string path)
    {
        throw new NotImplementedException();
    }
}

Но я не знаю, как реализовать его на этом уровне, и я хотел бы отправить его на мою EntityFramework (или кому-либо еще, кто будет реализовывать IRepository) для работы.

Мне нужно то же самое для интерфейса с методом расширения.

Есть ли свет?

Ответы [ 3 ]

3 голосов
/ 22 июля 2011

Include - это утечка абстракции, которая работает только с платформой Entity. EF 4.1 уже содержит Include сверх универсального IQueryable, но он внутренне только преобразует переданные универсальные IQueryable в универсальные ObjectQuery или DbQuery и вызывает их Include.

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

2 голосов
/ 30 марта 2012

Этот вопрос немного устарел, но вот два EF-независимых решения, если вы или кто-то еще ищете:

1. Решение на основе отражений

Это решение - то, к чему возвращается .NET Framework, если IQueryable не приведен к DbQuery или ObjectQuery. Пропустите эти приведения (и эффективность, которую они обеспечивают), и вы отделите решение от Entity Framework.

public static class IncludeExtension  
{ 
    private static T QueryInclude<T>(T query, string path) 
    { 
        MethodInfo includeMethod = query.GetType().GetMethod("Include", new Type[] { typeof(string) });

        if ((includeMethod != null) && typeof(T).IsAssignableFrom(includeMethod.ReturnType))
        {
           return (T)includeMethod.Invoke(query, new object[] { path });
        }

        return query;
    }

    public static IQueryable<T> Include<T>(this IQueryable<T> query, string path) where T : class
    {
        return QueryInclude(query, path);
    }

    // Add other Include overloads.
} 

2. Решение на основе Dyanmics

Здесь метод QueryInclude<T> использует тип dynamic, чтобы избежать отражения.

public static class IncludeExtension  
{ 
    private static T QueryInclude<T>(T query, string path) 
    { 
        dynamic querytWithIncludeMethod = query as dynamic;

        try
        {
            return (T)querytWithIncludeMethod.Include(path);
        }
        catch (RuntimeBinderException)
        {
            return query;
        }
    }

    public static IQueryable<T> Include<T>(this IQueryable<T> query, string path) where T : class
    {
        return QueryInclude(query, path);
    }

    // Add other Include overloads.
} 
0 голосов
/ 03 апреля 2014

В Entity Framework 5.0 теперь они предоставляют метод расширения для IQueryable для добавления функции включения. Вам просто нужно добавить использование «System.Data.Entity» для разрешения метода расширения. Для прямой документации перейдите здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...