我的实体类:
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 |导航'[r] .Manufacturer'的包含操作是不必要的并且被忽略,因为在最终查询结果中无法访问导航。有关更多信息,请参阅https://go.microsoft.com/fwlink/?linkid=850303 ...
我在新的匿名中使用Manufacturer.name,这意味着必须使用导航[r] .Manufacturer。
为什么实体框架核心警告消息?我做错了吗?谢谢!
这实际上是一个关于实体框架qazxsw poi实际上做什么的常见误解。它实际上根本不影响过滤,但仅在结果具体化时才相关。
当你执行Include
时,你实际上告诉实体框架是这样的:当结果中有一个类型为something.Include(x => x.Prop)
的实体时,还包括导航属性something
可以访问的实体。
例如,按照EF Core文档使用的常用博客和帖子示例,Prop
将加载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(),
});
这将选择包含标题为“Foo”的帖子的所有context.Blogs
.Where(blog => blog.Posts.Any(post => title == "Foo"));
实体;但是Blog
导航属性不会被加载,因为它没有包含在查询中。但你仍然可以通过它过滤。
所以Posts
只会影响查询的结果,并且只有在生成该类型的实际实体时才会这样。但是,没有必要包含只是为了过滤它的东西。
在您的特定示例中,由于结果中没有任何.Include()
实体,因此包含Unit
无效。并且为了将Unit.Manufacturer
添加到结果中,您不需要包含导航属性。