首页 > 解决方案 > 在 Entity Framework Core 中重用包含语句

问题描述

我正在尝试制作可重用的包含,并且当我有特定的具体根实体时它目前可以工作。但是假设我有这样的结构:

public class A
{
    public B NavigationB { get; set; }
}

public class B
{
    public C NavigationC { get; set; }
}

public class C
{

}

我的包含扩展

public static class IncludeExtensions
{
    public static IQueryable<B> MyIncludesB(this IQueryable<B> query)
    {
        return query.Include(q => q.NavigationC);
    }

    public static IQueryable<A> MyIncludesA(this IQueryable<A> query)
    {
        return query.Include(q => q.NavigationB)
            .MyIncludesB(); // how can I implement this
    }
}

如果我有单个根目录,基本上一切都很好A,但是如果我想使用根目录进行获取怎么办B?这个想法是包含所有需要的东西B,但是当A作为 root 使用时,包含所有东西A,当包含时B,重用MyIncludesB

我不确定这是否可行,因为 include 正在返回IIncludableQueryable<A, B>,但如果有人有任何建议,请随时提供帮助!

标签: entity-framework-corenavigation-properties

解决方案


我认为有很多可能性。

我的第一个想法是封装属性表达式:

public static class IncludeExtensions
{
    public static Expression<Func<B, C>> MyIncludeListB()
    {
        return q => q.NavigationC;
    }

    public static Expression<Func<A, B>> MyIncludeListA()
    {
        return q => q.NavigationB;
    }

    public static IQueryable<B> MyIncludesB(this IQueryable<B> query)
    {
        return query.Include(MyIncludeListB());
    }

    public static IQueryable<A> MyIncludesA(this IQueryable<A> query)
    {
        return query.Include(MyIncludeListA()).ThenInclude(MyIncludeListB());
    }
}

如您所见,您可以传递Expression<Func<B, C>>给该方法Include

我的第二个想法是使用字符串实现包含.Include(string)

public static class IncludeExtensions2
{
    public static IEnumerable<string> MyIncludeListB()
    {
        return "NavigationC".Split(";");
    }

    public static IEnumerable<string> MyIncludeListA()
    {
        return "NavigationB;NavigationB.NavigationC".Split(";");
    }

    public static IQueryable<B> MyIncludesB(this IQueryable<B> query)
    {
        foreach (var i in MyIncludeListB())
        {
            query = query.Include(i);
        }

        return query;
    }

    public static IQueryable<A> MyIncludesA(this IQueryable<A> query)
    {
        foreach (var i in MyIncludeListA())
        {
            query = query.Include(i);
        }

        return query;
    }
}

如您所见,您可以传递string给方法Include。您可以传递完整的导航属性链。

如果要实现多个导航属性,则必须相应地修改两个代码示例。

已经有一些像你这样的问题和答案:

简单:实体框架 - 包括多个级别的属性

难:EF Core 中的多个 Includes()


推荐阅读