如何使实体框架将扩展方法包含在Generic IQueryable <TSource>中

iur*_*ona 5 methods entity-framework code-first

这就是事情.

我有一个接口,我想把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);
}
Run Code Online (Sandbox Code Playgroud)

所以我有扩展方法:

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

但我不知道如何在这一层实现它,我想把它发送到我的EntityFramework(或任何将实现IRepository的人)来处理.

我需要一个带扩展方法的接口.

有光吗?

Xac*_*ron 2

这个问题有点老了,但如果您或其他人仍在寻找,这里有两个独立于 EF 的解决方案:

1.基于反射的解决方案

IQueryable如果不转换为 aDbQuery或 ,则 .NET Framework 会使用此解决方案ObjectQuery。跳过这些转换(及其提供的效率),您就可以将解决方案与实体框架解耦。

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.
} 
Run Code Online (Sandbox Code Playgroud)

2. 基于动力学的解决方案

这里该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.
} 
Run Code Online (Sandbox Code Playgroud)