实体框架 - 包含多个属性级别

时间:2012-05-30 19:07:45

标签: c# entity-framework

Include()方法适用于对象列表。但是,如果我需要深入两个级别呢?例如,下面的方法将返回ApplicationServers,其中包含此处显示的包含属性。但是,ApplicationsWithOverrideGroup是另一个容纳其他复杂对象的容器。我也可以在该属性上执行Include()吗?或者我怎样才能使该属性完全加载?

现在看来,这个方法:

public IEnumerable<ApplicationServer> GetAll()
{
    return this.Database.ApplicationServers
        .Include(x => x.ApplicationsWithOverrideGroup)                
        .Include(x => x.ApplicationWithGroupToForceInstallList)
        .Include(x => x.CustomVariableGroups)                
        .ToList();
}

将仅填充Enabled属性(下方),而不填充Application或CustomVariableGroup属性(如下所示)。我该如何实现这一目标?

public class ApplicationWithOverrideVariableGroup : EntityBase
{
    public bool Enabled { get; set; }
    public Application Application { get; set; }
    public CustomVariableGroup CustomVariableGroup { get; set; }
}

9 个答案:

答案 0 :(得分:597)

适用于EF 6

using System.Data.Entity;

query.Include(x => x.Collection.Select(y => y.Property))

有关更多示例,请参阅Remarks

确保添加using System.Data.Entity;以获取带有lambda的Include版本。


适用于EF Core

使用新方法ThenInclude

query.Include(x => x.Collection)
     .ThenInclude(x => x.Property);

答案 1 :(得分:58)

如果我理解正确,您会询问是否包含嵌套属性。如果是这样的话:

.Include(x => x.ApplicationsWithOverrideGroup.NestedProp)

.Include("ApplicationsWithOverrideGroup.NestedProp")  

.Include($"{nameof(ApplicationsWithOverrideGroup)}.{nameof(NestedProp)}")  

答案 2 :(得分:40)

EF Core:使用“ThenInclude”加载多个级别: 例如:

var blogs = context.Blogs
    .Include(blog => blog.Posts)
        .ThenInclude(post => post.Author)
        .ThenInclude(author => author.Photo)
    .ToList();

答案 3 :(得分:25)

我为Entity Framework 6(.Net Core样式)做了一个小帮手,以很好的方式包含子实体。

现在在NuGet上:Install-Package ThenInclude.EF6

using System.Data.Entity;

var thenInclude = context.One.Include(x => x.Twoes)
    .ThenInclude(x=> x.Threes)
    .ThenInclude(x=> x.Fours)
    .ThenInclude(x=> x.Fives)
    .ThenInclude(x => x.Sixes)
    .Include(x=> x.Other)
    .ToList();

套餐为available on GitHub

答案 4 :(得分:15)

我还必须使用多个包含,在第3级我需要多个属性

(from e in context.JobCategorySet
                      where e.Id == id &&
                            e.AgencyId == agencyId
                      select e)
                      .Include(x => x.JobCategorySkillDetails)
                      .Include(x => x.Shifts.Select(r => r.Rate).Select(rt => rt.DurationType))
                      .Include(x => x.Shifts.Select(r => r.Rate).Select(rt => rt.RuleType))
                      .Include(x => x.Shifts.Select(r => r.Rate).Select(rt => rt.RateType))
                      .FirstOrDefaultAsync();

这可能有助于某人:)

答案 5 :(得分:10)

更多EFCore examples on MSDN表示您可以使用IncludeThenInclude完成一些相当复杂的事情。

这是一个很好的例子,说明你可以得到多么复杂(这是一个声明!):

viewModel.Instructors = await _context.Instructors

      .Include(i => i.OfficeAssignment)

      .Include(i => i.CourseAssignments)
        .ThenInclude(i => i.Course)
            .ThenInclude(i => i.Enrollments)
                .ThenInclude(i => i.Student)

      .Include(i => i.CourseAssignments)
        .ThenInclude(i => i.Course)
            .ThenInclude(i => i.Department)

      .AsNoTracking()
      .OrderBy(i => i.LastName)
      .ToListAsync();

了解如何在Include之后将ThenInclude链接到ThenIncludes并进行重置&#39;你回到顶级实体(教练)的水平。

你甚至可以重复相同的第一级&#39;集合(CourseAssignments)多次,然后是单独的Include命令,以获取不同的子实体。

请注意,您的实际查询必须标记在ThenIncludesvar query = _context.Instructors.AsQueryable(); query.Include(i => i.OfficeAssignment); var first10Instructors = query.Take(10).ToArray(); 链的末尾。以下不起作用:

AsNoTracking

强烈建议您设置日志记录,并确保如果您包含一两件以上的内容,您的查询就不会失控。了解它的实际工作方式非常重要 - 而且您会注意到每个单独的包含&#39;通常是一个新的查询,以避免大量连接返回冗余数据。

如果您不打算实际编辑实体并重新保存,

<input type="file" id="documents" name="documents[]" multiple> 可以大大加快速度。

答案 6 :(得分:3)

让我清楚地说一下,如果您不介意使用字符串文字,则可以使用字符串重载来包含嵌套级别,而不考虑对应关系的多重性:

query.Include("Collection.Property")

答案 7 :(得分:0)

我将为我的特定问题添加解决方案。我有两个需要收集的同一级别的收藏。最终的解决方案看起来像这样。

var recipe = _bartendoContext.Recipes
    .Include(r => r.Ingredients)
    .ThenInclude(r => r.Ingredient)
    .Include(r => r.Ingredients)
    .ThenInclude(r => r.MeasurementQuantity)
    .FirstOrDefault(r => r.Id == recipeId);
if (recipe?.Ingredients == null) return 0m;
var abv = recipe.Ingredients.Sum(ingredient => ingredient.Ingredient.AlcoholByVolume * ingredient.MeasurementQuantity.Quantity);
return abv;

这是根据给定饮料配方的体积计算酒精百分比。如您所见,我只是将成分集合添加了两次,然后在其中添加了成分和数量。

答案 8 :(得分:0)

我想出了一个最简单的方法。您不需要安装包 ThenInclude.EF 或者不需要对所有嵌套导航属性使用 ThenInclude。如下图所示,EF会为您照顾休息。 例子:

var thenInclude = context.One.Include(x => x.Twoes.Threes.Fours.Fives.Sixes)
.Include(x=> x.Other)
.ToList();