如何将Entity Framework的Include扩展方法应用于通用的IQueryable<TSource>?

5

事情是这样的。

我有一个接口,我想把属于EntityFramework库的Include扩展方法放在我的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
Include是一个不完美的抽象,仅适用于Entity Framework。EF 4.1 已经包含了通用的IQueryable接口,但它在内部只将传递的通用IQueryable转换为通用的ObjectQueryDbQuery,并调用它们的Include方法。
以下是如何在存储库中封装这个include方法的示例(存储库实现依赖于EF,因此可以直接使用由EF提供的Include)。

所以,我不想依赖EF。我试图避免在客户端层中引用它。 - iuristona

2

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

1. 基于反射的解决方案

如果 IQueryable 不能转换为 DbQueryObjectQuery,则 .NET Framework 会使用此解决方案。跳过这些转换(以及所提供的效率),您就可以将该解决方案从 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. 基于动态类型的解决方案

在这里,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
在 Entity Framework 5.0 中,它们现在提供了一个扩展方法来为 IQueryable 添加 Include 功能。您只需要添加 using "System.Data.Entity" 来解决扩展方法。有关详细文档,请单击 此处

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接