实体框架核心显示警告消息

Loc*_*Loc 1 entity-framework entity-framework-core .net-core asp.net-core entity-framework-core-2.1

我的实体类别:

public class Unit
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int? UnitID { get; set; }

    public string Name { get; set; }

    [Required]
    public int? ManufacturerID { get; set; }

    // More fields

    public Manufacturer Manufacturer { get; set; }
}

public class Manufacturer
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int? ManufacturerID { get; set; }

    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我的查询:

        return await DbContext.Unit.AsNoTracking().Include(r => r.Manufacturer)
                .Select(r => new
                {
                    UnitID = r.UnitID,
                    UnitName = r.Name,
                    ManufacturerName = r.Manufacturer.Name // Using Manufacturer
                }).ToListAsync();
Run Code Online (Sandbox Code Playgroud)

警告信息:

... | WARN | Microsoft.EntityFrameworkCore.Query |导航'[r] .Manufacturer'的Include操作是不必要的,由于在最终查询结果中无法导航,因此忽略了该操作。有关更多信息,请参阅https://go.microsoft.com/fwlink/?linkid=850303。

我正在使用新的匿名服务器中的Manufacturer.name,因此这意味着导航[r] .Manufacturer必须使用。

为什么Entity Framework Core警告消息?做错了吗?谢谢!

pok*_*oke 7

实际上,这是对实体框架实际作用的普遍误解Include。实际上,它根本不影响过滤,而仅在实现结果时才相关。

当执行something.Include(x => x.Prop)此操作时,您实际上要告诉Entity Framework的内容是:当结果中存在类型为something的实体时,还包括navigation属性可访问的实体Prop。

例如,按照EF Core文档使用的常规博客和帖子示例,context.Blogs.Include(blog => blog.Posts)将加载Blog实体并包括与Posts每个Blog实体相关的实体。但这仅在您实际Blog在结果中选择实体时才重要。

context.Blogs
    .Select(blog => new {
        Id = blog.BlogId,
        Url = blog.Url,
    });
Run Code Online (Sandbox Code Playgroud)

例如,此查询不会产生任何Blog实体,因此该Blog实体上的包含将被忽略。您也可以扩展此查询,以包含有关帖子的信息,而无需实际Posts在Blog实体上包含navigation属性。由于Blog结果中没有实体,因此不会产生任何影响:

context.Blogs
    .Select(blog => new {
        Id = blog.BlogId,
        Url = blog.Url,
        PostCount = blog.Posts.Count(),
    });
Run Code Online (Sandbox Code Playgroud)

请注意,不包括导航属性并不能阻止您使用它来过滤某些内容:

context.Blogs
    .Where(blog => blog.Posts.Any(post => title == "Foo"));
Run Code Online (Sandbox Code Playgroud)

这将选择所有Blog包含标题为“ Foo”的帖子的实体;但由于Posts导航属性未包含在查询中,因此不会加载。但是您仍然可以通过它进行过滤。


因此.Include()只会影响查询的结果,并且仅当存在要生成该类型的实际实体时才如此。但是,没有必要仅包含一些内容来进行过滤。

在您的特定示例中,由于Unit结果中没有任何实体,所以包含Unit.Manufacturer无效。并且为了将,添加Unit.Manufacturer.Name到结果中,您不需要包括navigation属性。