Entity Framework Core показывает предупреждение - PullRequest
0 голосов
/ 17 сентября 2018

Мои классы сущностей:

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]. Производитель» не нужно и был проигнорирован, потому что навигация недоступна в последнем запросе Результаты. Подробнее см. https://go.microsoft.com/fwlink/?linkid=850303 информация ...

Я использую Мануфактурное имя в новом анонимном сообщении, поэтому оно означает навигацию [r]. Необходимо использовать производителя.

Почему Entity Framework Core предупреждает сообщение? Я делаю не так? Спасибо!

1 Ответ

0 голосов
/ 18 сентября 2018

На самом деле это распространенное заблуждение относительно того, что на самом деле делает Include Entity Framework.Это на самом деле не влияет на фильтрацию вообще, но имеет значение только тогда, когда результат материализуется.

Когда вы делаете something.Include(x => x.Prop), то, что вы на самом деле говорите Entity Framework, это: Когда существует сущность типаравным 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"));

При этом будут выбраны все Blog сущности, которые содержат пост с заголовком «Foo»;но свойство навигации Posts не будет загружено, поскольку оно не включено в запрос.Но вы все равно можете фильтровать по нему.


Таким образом, .Include() повлияет только на результат запроса и только в том случае, если существует фактическая сущность этого типа, которая создается.Однако не обязательно включать что-то, чтобы просто отфильтровать по нему.

В вашем конкретном примере, поскольку в результате нет никакого объекта Unit, включение Unit.Manufacturer не имеет никакого эффекта.И чтобы добавить Unit.Manufacturer.Name к результату, вам не нужно включать свойство навигации.

...