2016-11-24 9 views
0

Недавно добавленное EF Core добавило явно навигационные свойства объекта;Явно загружать все навигационные свойства

using (var db = new BloggingContext()) { 
    var blog = db.Blogs.Find(1); 

    db.Entry(blog).Collection(b => b.Posts).Load(); 
    db.Entry(blog).Reference(b => b.Author).Load(); 
} 

https://blogs.msdn.microsoft.com/dotnet/2016/11/16/announcing-entity-framework-core-1-1/

Это, очевидно, многословен, и я не хочу, чтобы сделать эти проверки каждый раз. Существуют ли какие-либо методы расширения или дополнительные пакеты NuGet для устранения этих недостатков?

Я понимаю, что это общий вопрос, но не для EF Core.

EntityFramework Eager Load all Navigation Properties

+0

Does '.Include (..)' не работает в ядре? то есть. 'db.Blogs.Include (m => m.Posts) .Include (m => m.Author) .Find (1);' –

+0

Да, но я пытаюсь обойти явное указание объектов, которые я хочу. https://docs.microsoft.com/en-us/ef/core/querying/related-data – wonea

+0

А, извините, поэтому ваш вопрос заключается в том, как загрузить все навигационные реквизиты с этой модели. Я неправильно понял название и попытался просто упростить его. Я мог бы думать о простом способе сделать это с Reflection, но не уверен, что есть встроенный метод даже для старого EF. EDIT: Даже вопрос, с которым вы связались, будет работать для Core, поскольку вы все еще указываете, что загрузить. EDIT2: Я мог ошибаться, но я думаю, что '.Include (..)' быстрее, чем загрузка по отдельности, так как они станут частью первоначального запуска запроса. –

ответ

1

Как уже упоминалось в комментариях, я довольно уверенно (хотя мое использование EF Ядра ограничена), что это не может быть сделано автоматически с помощью стандартного отображения навигационных свойств. Кроме того, использование .Load менее эффективно (и намного дольше), чем при использовании .Include, поскольку вы будете запускать несколько запросов так же, как и само по себе ленивое навигационное свойство.

Есть два способа, которые я могу придумать, чтобы подойти к проблеме не желая делать проверки каждый раз в соответствии с вашим вопросом. Первый будет работать для загрузки вашего объекта Blog, а второй - для повторного использования между другими, но все еще требует изменений в вашей загрузке.

1; Метод расширения для загрузки всех связанных сущностей, что-то вроде этого:

public static IQueryable<Blog> EagerWhere(this DbSet<Blogs> dbset, Expression<Func<Blog, bool>> expr) { 
    return dbset 
     .Include(m => m.Posts) 
     .Include(m => m.Author) 
     .Where(expr); 
} 

// .. usage 

db.Blogs.EagerWhere(m => m.Id == 1); 

(Обратите внимание, что я написал это как EagerWhere, так что вы имеете больше контроля над запросом, так что это более многоразовые, а не простой Find замены)

2; Напишите пользовательский атрибут и напишите метод, аналогичный описанному выше, который выполняет то же действие, что и .Find(..), но использует Reflection для поиска свойств с вашим настраиваемым атрибутом и рекурсивно передает их в .Include(..).

Я не буду писать пример для этого, так как я не уверен, что это стоит усилий из-за (обычно) ограниченного количества созданных объектов.

+0

Afaik dotnet core еще не поддерживает свойство propertyInfo. – alanh

+0

@alanh Хм, я так и думал. Конечно, это не так, но это не так важно. Я не могу сказать наверняка, хотя у меня не было возможности снова схватиться с Core снова с RC2. –

Смежные вопросы