如何将实体框架包含扩展方法引入通用 IQueryable

发布于 2024-11-25 20:11:06 字数 805 浏览 6 评论 0原文

事情是这样的。

我有一个接口,我会将属于 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的人)来处理。

我需要同样的具有扩展方法的接口。

有光吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

半透明的墙 2024-12-02 20:11:06

Include 是有漏洞的抽象,它仅适用于实体框架。 EF 4.1 已包含 包含在通用IQueryable上,但它在内部仅将传递的通用IQueryable转换为通用ObjectQueryDbQuery 并调用它们的Include

以下是如何包装包含在存储库中 (存储库实现依赖于 EF,因此可以直接使用 EF 提供的 Include)。

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

古镇旧梦 2024-12-02 20:11:06

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

1。基于反射的解决方案

如果 IQueryable 未转换为 DbQueryObjectQuery,.NET 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 方法使用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.
} 

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.
} 
隔岸观火 2024-12-02 20:11:06

在 Entity Framework 5.0 中,它们现在提供了 IQueryable 的扩展方法来添加 Include 功能。您只需要添加一个 using“System.Data.Entity”即可解析扩展方法。如需直接文档,请访问此处

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文