简体   繁体   English

Entity Framework Core:使用 AsNoTracking 过滤 Include 时的奇怪行为

[英]Entity Framework Core: strange behaviour when filtering on Include with AsNoTracking

I don't know if it is expected to be this way but I thought it is strange since changes the query results.我不知道是否应该这样,但我认为这很奇怪,因为更改了查询结果。

When I execute the query below I get my entity with only 2 "Mensagens" entity because i'm filtering only the actives so it's right, I have 2 active entities on my database and 1 inactive.当我执行下面的查询时,我得到的实体只有 2 个“Mensagens”实体,因为我只过滤活动实体,所以这是正确的,我的数据库中有 2 个活动实体和 1 个不活动实体。

return await context.Lancamentos
            .Include(x => x.UsuarioCriacao)
            .Include(x => x.Mensagens.Where(m => m.Ativo))
            .ThenInclude(m => m.MensagemMedias)
            .ThenInclude(m => m.MediaWhatsapp)
            .ThenInclude(m => m.TipoMediaWhatsapp)
            .Include(x => x.Mensagens.Where(m => m.Ativo))
            .ThenInclude(x => x.TemplateMensagem)
            .ThenInclude(t => t.Medias)
            .ThenInclude(m => m.MediaWhatsapp)
            .ThenInclude(m => m.TipoMediaWhatsapp)
            .AsNoTracking()
            .FirstOrDefaultAsync(l => l.Id == id && l.Ativo);

在此处输入图像描述

But if I execute the exact same command just removing the AsNoTracking() line it gives me the 3 records, both active and inactive.但是,如果我执行完全相同的命令,只是删除AsNoTracking()行,它会给我 3 条记录,包括活动的和非活动的。

在此处输入图像描述

But the inactive one EF doesn't fetch the ThenInclude below.但是不活动的 EF 不会获取下面的ThenInclude It changes the behaviour.它改变了行为。

With AsNoTracking it filters the data according to the filter I used on Include使用AsNoTracking ,它会根据我在Include上使用的过滤器过滤数据

Without AsNoTracking it bring me all the data but it filters if it will load or not the ThenInclude objects.如果没有AsNoTracking ,它会给我带来所有数据,但它会过滤是否会加载ThenInclude对象。

Does anyone know if this is a normal behaviour and why does it behaves like this?有谁知道这是否是正常行为以及为什么会这样?

When handling with complex query like that I used to use Linq instead of Lambda to be sure I'm make me clear enough to my colleagues and to myself in the future.在处理这样的复杂查询时,我曾经使用Linq而不是Lambda来确保我对我的同事和我自己的未来足够清楚。

To understand what's going on with your query I should say the identation matters a lot.要了解您的查询发生了什么,我应该说身份很重要。 For example, is that what I am understanding from your query:例如,这是我从您的查询中了解到的:

return await context.Lancamentos
            .Include(x => x.UsuarioCriacao)
            .Include(x => x.Mensagens.Where(m => m.Ativo))
                .ThenInclude(m => m.MensagemMedias)
                    .ThenInclude(m => m.MediaWhatsapp)
                        .ThenInclude(m => m.TipoMediaWhatsapp)
            .Include(x => x.Mensagens.Where(m => m.Ativo))
                .ThenInclude(x => x.TemplateMensagem)
                    .ThenInclude(t => t.Medias)
                        .ThenInclude(m => m.MediaWhatsapp)
                            .ThenInclude(m => m.TipoMediaWhatsapp)
                                .AsNoTracking()
            .FirstOrDefaultAsync(l => l.Id == id && l.Ativo);

And I feel like it's what you really want is something like that:我觉得你真正想要的是这样的:

return await (context.Lancamentos
            .Include(x => x.UsuarioCriacao)
            .Include(x => x.Mensagens.Where(m => m.Ativo))
                .ThenInclude(m => m.MensagemMedias)
                    .ThenInclude(m => m.MediaWhatsapp)
                        .ThenInclude(m => m.TipoMediaWhatsapp)
            .Include(x => x.Mensagens.Where(m => m.Ativo))
                .ThenInclude(x => x.TemplateMensagem)
                    .ThenInclude(t => t.Medias)
                        .ThenInclude(m => m.MediaWhatsapp)
                            .ThenInclude(m => m.TipoMediaWhatsapp))
            .AsNoTracking()
            .FirstOrDefaultAsync(l => l.Id == id && l.Ativo);

The difference could be explained by the different contexts between the first message restrictions and the second one.差异可以通过第一个消息限制和第二个消息限制之间的不同上下文来解释。 One of the messages is being retrieved twice because one of it's instance is in and the other one is outside the ef context.其中一条消息被检索了两次,因为其中一条实例位于其中,另一条位于 ef 上下文之外。

You should check again the docs about the ThenInclude and the AsNoTracking extension methods to be sure you are using it in the right way.您应该再次检查有关ThenIncludeAsNoTracking扩展方法的文档,以确保您以正确的方式使用它。

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

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