简体   繁体   English

忽略有关生成查询表达式 EF Core 的 ThenInclude 语句

[英]Ignored ThenInclude statement on generating query expression EF Core

Foreword:前言:

I have 2 projects on .NET Core 3.1, one EF Core 3.1.17 and another on 5.0.10 and in both I've used Include/ThenInclude the same way and all works good.我在 .NET Core 3.1 上有 2 个项目,一个在 EF Core 3.1.17 上,另一个在 5.0.10 上,在这两个项目中我都以相同的方式使用了 Include/ThenInclude,并且一切正常。 Now I'm trying upgrade my project on 3.1.17 to version 5.0.10 and got some weird situation.现在我正在尝试将我在 3.1.17 上的项目升级到 5.0.10 版本并且遇到了一些奇怪的情况。

Problem:问题:

When I'm trying to use ThenInclude statement in expression all entities in ThenInclude are ignoring when EF generate a query.当我尝试在表达式中使用 ThenInclude 语句时,当 EF 生成查询时, ThenInclude 中的所有实体都将被忽略。

It's my expression:这是我的表达:

var settings = await _dbRepository.GetRegionRoles(systemId)
            .Include(r => r.Region)
            .Include(sr => sr.SystemRole)
            .ThenInclude(ro => ro.Role)
            .Include(gs => gs.GroupSettings)
            .Where(w => w.GroupSettings.Any())
            .ToListAsync(cancellationToken);

And EF recognize all ThenInclude statement before generating query(I tried to add some more where it's possible and got the same result), there is trace log:并且 EF 在生成查询之前识别所有 ThenInclude 语句(我尝试在可能的地方添加更多并得到相同的结果),有跟踪日志:

 Compiling query expression: 
'DbSet<RegionRole>()
    .Include(x => x.SystemRole)
    .Where(w => w.SystemRole.SystemId.Equals((int)__systemId_0))
    .Include(r => r.Region)
    .Include(sr => sr.SystemRole)
    .ThenInclude(ro => ro.Role)
    .Include(gs => gs.GroupSettings)
    .Include(sr => sr.SystemRole)
    .ThenInclude(s => s.SystemCode)
    .Where(w => w.GroupSettings
        .Any())'

But result of generation looks like:但生成的结果如下:

Generated query execution expression: 
'queryContext => new SingleQueryingEnumerable<RegionRole>(
    (RelationalQueryContext)queryContext, 
    RelationalCommandCache.SelectExpression(
        Projection Mapping:
        SELECT r.Id, r.CreatedByUser, r.CreatedDate //... and many other fields from each table
        FROM Main.RegionRole AS r
        INNER JOIN Main.SystemRole AS s ON r.SystemRoleId == s.Id
        INNER JOIN Main.Region AS r0 ON r.RegionId == r0.Id
        LEFT JOIN Main.GroupSettings AS g ON r.Id == g.RegionRoleId
        WHERE (s.SystemId == CAST(@__systemId_0) AS int)) && EXISTS (
            Projection Mapping:
            SELECT 1
            FROM Main.GroupSettings AS g0
            WHERE (r.Id != NULL) && (r.Id == g0.RegionRoleId))
        ORDER BY r.Id ASC, s.Id ASC, r0.Id ASC, g.Id ASC), 
    Func<QueryContext, DbDataReader, ResultContext, SingleQueryResultCoordinator, RegionRole>, 
    K2Project.BE.DAL.Models.K2DbContext, 
    False, 
    False
)'

So as we can see here, entity "Role" that is in ThenInclude statement is missing in result.因此,正如我们在此处看到的,结果中缺少 ThenInclude 语句中的实体“角色”。

All entities has navigation properties and described in fluent api.所有实体都有导航属性并在 fluent api 中描述。 All tables have foreign keys.所有表都有外键。

There is an example of entity "SystemRole"有一个实体“SystemRole”的例子

public class SystemRole
{        
    public Guid Id { get; set; }

    public int RoleId { get; set; }        

    #region Dependencies

    public virtual Role Role { get; set; }

    #endregion
 }

And fluent api:和流利的api:

public class SystemRoleEntityTypeConfiguration : IEntityTypeConfiguration<SystemRole>
{
    public void Configure(EntityTypeBuilder<SystemRole> builder)
    {
        builder.ToTable(nameof(SystemRole), DbConst.MainSchemaName);

        builder.HasKey(p => p.Id);

        builder.Property(p => p.Id)
            .ValueGeneratedOnAdd()
            .HasDefaultValueSql("NEWSEQUENTIALID()");

        builder.HasOne(p => p.Role)
            .WithMany()
            .HasForeignKey(f => f.RoleId)
            .IsRequired(true);

    }
}

Question:问题:

What is difference between usage of ThenInclude in EF Core version 3.1.17 and 5.0.10 and why the same expression works on first version but don't works on another?在 EF Core 版本 3.1.17 和 5.0.10 中使用 ThenInclude 有什么区别,为什么相同的表达式适用于第一个版本但不适用于另一个版本? Maybe I did something wrong or forget to change something when changed the framework version?也许我做错了什么或在更改框架版本时忘记更改某些内容?

PS In my second project that was from beginning on EF Core 5.0.10 all expressions with Include/ThenInclude statements doing great. PS 在我从 EF Core 5.0.10 开始的第二个项目中,所有带有 Include/ThenInclude 语句的表达式都做得很好。

That shows why it's important to include all code in questions.这说明了为什么在问题中包含所有代码很重要。

This is the GetRegionRoles method :这是GetRegionRoles方法:

public IQueryable<RegionRole> GetRegionRoles(SystemCodesEnum systemId)
{
    return _context.RegionRole
        .Include(x => x.SystemRole)
        .Where(w => w.SystemRole.SystemId.Equals((int)systemId));
}

So it already contains an Include and the same Include is repeated in your query:因此它已经包含一个Include并且在您的查询中重复了相同的Include

var settings = await _dbRepository.GetRegionRoles(systemId)
            .Include(r => r.Region)
            .Include(sr => sr.SystemRole) // <= here
                .ThenInclude(ro => ro.Role)
            .Include(gs => gs.GroupSettings)
            .Where(w => w.GroupSettings.Any())
            .ToListAsync(cancellationToken);

When I reproduce this code I see that, apparently, EF is sensitive to placement of Include statements.当我重现这段代码时,我看到,显然,EF 对Include语句的位置很敏感。 In this case the similar Includes are separated by a Where statement.在这种情况下,类似的包含由Where语句分隔。 Somehow that causes EF (core 5) to ignore the repeated Include (followed by ThenInclude ).不知何故,这导致 EF(核心 5)忽略重复的Include (后跟ThenInclude )。 It works if you remove the separation, simply by moving the Where statement:如果您删除分隔,它可以工作,只需移动Where语句:

public IQueryable<RegionRole> GetRegionRoles(SystemCodesEnum systemId)
{
    return _context.RegionRole
        .Where(w => w.SystemRole.SystemId.Equals((int)systemId))
        .Include(x => x.SystemRole);
}

I assume this is not intended behavior (why would it?).我认为这不是预期的行为(为什么会这样?)。 You may want to post a bug report, or see if it still happens in version 6.您可能想发布一个错误报告,或者看看它是否仍然在版本 6 中发生。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM