我的实体类:
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会警告该消息?做错了吗?谢谢!
答案 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属性。