How to brings the Entity Framework Include extention method to a Generic IQueryable<TSource>

戏子无情 提交于 2019-12-06 03:08:28

问题


Here's the thing.

I have an interface, and I would to put the Include extension method, who belongs to EntityFramework library, to my IRepository layer wich dont needs to knows about 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);
}

So I have the extension method:

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

But I don't know how to implement it in this layer, and I would to send it to my EntityFramework (or whatever who will implement the IRepository) to deal with.

I need same to a Interface with a extension method.

Any light?


回答1:


This question is a bit old, but here are two EF-independent solutions if you or anyone else is still looking:

1. Reflection-based Solution

This solution is what the .NET Framework falls back to if the IQueryable does not cast to a DbQuery or ObjectQuery. Skip these casts (and the efficiency it provides) and you've decoupled the solution from 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-based Solution

Here the QueryInclude<T> method uses the dynamic type to avoid reflection.

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.
} 



回答2:


Include is leaky abstraction and it works only with Entity framework. EF 4.1 already contains Include over generic IQueryable but it internally only converts passed generic IQueryable to generic ObjectQuery or DbQuery and calls their Include.

Here is some example how to wrap that include in repository (repository implementation is dependent on EF so it can use Include provided by EF directly).




回答3:


In Entity Framework 5.0 they now provide an extension method to IQueryable to add the Include functionality. You will just need to add a using "System.Data.Entity" in order to resolve the extension method. For direct documentation go here



来源:https://stackoverflow.com/questions/6791591/how-to-brings-the-entity-framework-include-extention-method-to-a-generic-iquerya

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!