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

Bob*_*orn 335 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();
}
Run Code Online (Sandbox Code Playgroud)

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

public class ApplicationWithOverrideVariableGroup : EntityBase
{
    public bool Enabled { get; set; }
    public Application Application { get; set; }
    public CustomVariableGroup CustomVariableGroup { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

Die*_*res 648

对于EF 6

using System.Data.Entity;

query.Include(x => x.Collection.Select(y => y.Property))
Run Code Online (Sandbox Code Playgroud)

有关更多示例,请参阅备注.

确保添加using System.Data.Entity;以获取Includelambda 的版本.


对于EF Core

使用新方法 ThenInclude

query.Include(x => x.Collection)
     .ThenInclude(x => x.Property);
Run Code Online (Sandbox Code Playgroud)

  • 请记住在usings中包含System.Data.Entity.否则,Intellisense将仅为您提供方法的Include(字符串路径)版本. (54认同)
  • @Adeem你需要为每个属性调用`Include`:`Db.States.Include(state => state.Cities.Select(city => city.Customers).Include(state => state.Cities.Select(city = > city.Vendors)` (4认同)

Jud*_*udo 61

如果我理解正确,那么你要问的是包含嵌套属性.如果是这样 :

.Include(x => x.ApplicationsWithOverrideGroup.NestedProp)
Run Code Online (Sandbox Code Playgroud)

要么

.Include("ApplicationsWithOverrideGroup.NestedProp")  
Run Code Online (Sandbox Code Playgroud)

要么

.Include($"{nameof(ApplicationsWithOverrideGroup)}.{nameof(NestedProp)}")  
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,我可以试试.我希望能够保持强类型并避免使用字符串文字.但如果这就是必须要做的...... (4认同)
  • 请记住在使用中包含 **System.Data.Entity**。否则 Intellisense 只会为您提供该方法的 `Include(string path)` 版本。 (2认同)
  • 您好,如果对于 EF core 这确实有效 .Include(x =&gt; x.ApplicationsWithOverrideGroup.NestedProp) 如果是这样,那么使用 Include / ThenInclude 有什么意义,因为它们都可以工作并生成相同的 SQL。我错过了什么吗? (2认同)

tha*_*cao 45

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

var blogs = context.Blogs
    .Include(blog => blog.Posts)
        .ThenInclude(post => post.Author)
        .ThenInclude(author => author.Photo)
    .ToList();
Run Code Online (Sandbox Code Playgroud)

  • 看起来这只是EF Core (51认同)
  • 仅供参考:VS2017 intellisense不适用.ThenInclude.只需按照您认为的方式键入它,错误突出显示就应该消失. (19认同)
  • 我想强调@JohnWrensby的评论,Intellisense有时需要特别长的时间来处理这些ThenInclude,这对新用户来说可能会让人感到困惑.我还有一些情况,其中简单的Include lambda表达式未正确处理,直到您只需键入并编译它,忽略VS中显示的"错误". (2认同)

小智 27

我为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();
Run Code Online (Sandbox Code Playgroud)

该软件包可在GitHub上获得.

  • @ lenny32有什么要注意这个扩展名? (2认同)

dnx*_*xit 19

我还必须使用多个包含,在第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();
Run Code Online (Sandbox Code Playgroud)

这可能有助于某人:)


Sim*_*ver 15

MSDN上的更多EFCore示例表明,您可以使用Include和执行一些非常复杂的操作ThenInclude.

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

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();
Run Code Online (Sandbox Code Playgroud)

看看你如何能够连结Include,ThenInclude然后它会"重置"你回到顶级实体(教练)的水平.

您甚至可以多次重复相同的"第一级"集合(CourseAssignments),然后使用单独的ThenIncludes命令来访问不同的子实体.

请注意,您的实际查询必须标记在IncludeThenIncludes链的末尾.以下不起作用:

var query = _context.Instructors.AsQueryable();
query.Include(i => i.OfficeAssignment);

var first10Instructors = query.Take(10).ToArray();
Run Code Online (Sandbox Code Playgroud)

强烈建议您设置日志记录,并确保如果您包含一两件以上的内容,您的查询不会失控.重要的是要看它是如何工作的 - 你会注意到每个单独的'include'通常是一个新的查询,以避免大量连接返回冗余数据.

AsNoTracking 如果您不打算实际编辑实体并重新保存,可以大大加快速度.


mrm*_*hal 8

让我明确指出,如果您不介意使用字符串文字,您可以使用字符串重载来包含嵌套级别,而不管对应关系的多重性如何:

query.Include("Collection.Property")
Run Code Online (Sandbox Code Playgroud)