2013-09-14 2 views
14

Я использую шаблон репозитория с DI и IoC.EntityFramework Eager Загрузить все свойства навигации

Я создал функцию в моем Repository:

T EagerGetById<T>(Guid id, string include) where T : class 
{ 
    return _dbContext.Set<T>().Include(include).Find(id); 
} 

Это охотно загрузить один свойство навигации в моей сущности права.

Но если мое лицо выглядит следующим образом:

public class Blog : PrimaryKey 
{ 
    public Author Author {get;set;} 
    public ICollection<Post> Posts {get;set;} 
} 

Как бы я жадную загрузку для Author и Posts? Был бы я в буквальном смысле слова сделать:

_dbContext.Set<T>().Include("Author").Include("Posts").Find(id); 

неизбежно производит такую ​​функцию:

T EagerGetById<T>(Guid id, string include, string include2, string include3) where T : class 
{ 
    return _dbContext.Set<T>().Include(include).Include(include2).Include(include3).Find(id); 
} 

Потому что это будет действительно неэффективна для Generic Repository!

ответ

23

Если вы не хотите использовать строки, вы также можете сделать то же самое для любого числа N из включает в себя, используя выражение, которое возвращает свойства навигации, чтобы быть готовы загружены. (Первоисточник here)

public IQueryable<TEntity> GetAllIncluding(params Expression<Func<TEntity, object>>[] includeProperties) 
{ 
    IQueryable<TEntity> queryable = GetAll(); 
   foreach (Expression<Func<TEntity, object>> includeProperty in includeProperties) 
    { 
    queryable = queryable.Include<TEntity, object>(includeProperty); 
   } 

    return queryable; 
} 
+0

Я действительно думал об этом, но легко ли в шаблоне репозитория с DI и IoC ?? –

+0

На втором взгляде ... context.Configuration.ProxyCreationEnabled = false; не вызывает интенсивной нагрузки. Это просто превращает прокси-создание. Вам все равно нужно включить include. Я редактирую его из ответа. –

+0

действительно ли это имеет смысл .... какой смысл в создании прокси-сервера, какие выгоды он дает ?! –

0

Если вам нужны все свойства навигации, у вас нет выбора, кроме как прочитать все данные из базы данных. Вы либо используете Include в своем запросе, либо читаете их заранее локальным данным DbSet.

Если вы хотите передать несколько включает в свой метод, просто определить его как это:

T EagerGetById<T>(Guid id, params string[] includes) 

Ваши пользователи смогут звонить EagerGetById(id, "inc1", "inc2", ...)

Внутри вашего метода, просто вызовите Include для каждого элемента в массиве includes.

Вы должны готовы о the params keyword

+0

См изменения, в частности, новый вид функции, которые должны быть созданы для этого ... –

+0

О, это не неэффективно, это просто некрасиво. Я отредактирую свой ответ. – zmbq

+0

Я все знаю о параметрах .. все еще не ответил на вопрос! Извините, чувак, это не режет! –

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