My entity classes:
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; }
}
My query:
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();
The warning message:
...|WARN|Microsoft.EntityFrameworkCore.Query|The Include operation for navigation '[r].Manufacturer' is unnecessary and was ignored because the navigation is not reachable in the final query results. See https://go.microsoft.com/fwlink/?linkid=850303 for more information...
I am using Manufacturer.name in new anonymous so It means navigation [r].Manufacturer must be used.
Why Entity Framework Core warns the message? Is am doing wrong? Thanks!
This is actually a common misconception about what Entity Framework’s
Include
actually does. It actually does not affect the filtering at all but is only relevant when the result is materialized.When you do
something.Include(x => x.Prop)
then what you are actually telling Entity Framework is this: When there is an entity of the type ofsomething
in the result, then also include the entity that is reachable by the navigation propertyProp
.For example, following the usual blogs & posts example that the EF Core documentation uses,
context.Blogs.Include(blog => blog.Posts)
will load theBlog
entities and include the relatedPosts
for eachBlog
entity. But this matters only if you actually selectBlog
entities in the result.This query for example does not produce any
Blog
entities, so includes on theBlog
entity would be ignored. You could also expand this query to also include information about the posts, without actually having to include thePosts
navigation property on theBlog
entity. Since there’s noBlog
entity in the result, that wouldn’t have any effect:Note that not including a navigational property does not prevent you from using it to filter something:
This would select all
Blog
entities that contained a post with a title “Foo”; but thePosts
navigation property wouldn’t be loaded since it wasn’t included in the query. But you can still filter by it.So
.Include()
will only affect the result of the query, and only if there is an actual entity of that type being produced. It is however not necessary to include something just to filter by it.In your particular example, since there isn’t any
Unit
entity in the result, the inclusion ofUnit.Manufacturer
has no effect. And in order to add theUnit.Manufacturer.Name
to the result, you do not need to include the navigation property.