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

时间:2018-09-17 19:56:25

标签: entity-framework asp.net-core .net-core entity-framework-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; }
}

我的查询:

        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();

警告消息:

  

... | WARN | Microsoft.EntityFrameworkCore.Query | The   不需要包含导航“ [r] .Manufacturer”的操作,并且   被忽略,因为在最终查询中无法访问导航   结果。有关更多信息,请参见https://go.microsoft.com/fwlink/?linkid=850303   信息...

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

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

1 个答案:

答案 0 :(得分:6)

这实际上是对Entity Framework Include实际功能的普遍误解。实际上,它根本不影响过滤,而仅在结果实现时才有意义。

当您执行something.Include(x => x.Prop)时,您实际上要告诉实体框架是这样的:当结果中存在something类型的实体时,还应包括实体可以到达的实体。导航属性Prop

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

context.Blogs
    .Select(blog => new {
        Id = blog.BlogId,
        Url = blog.Url,
    });

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

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

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

context.Blogs
    .Where(blog => blog.Posts.Any(post => title == "Foo"));

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


因此,.Include()仅会影响查询的结果,并且仅当产生了该类型的实际实体时才起作用。但是,不必仅包含一些内容即可对其进行过滤。

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