2016-09-07 5 views
1

Я использую Entity Framework и хотел бы создать общий GetByID метода в Repository класса с жадной загрузкой:Repository общего метода GetByID с помощью жадной загрузки

Вот мой метод, который использует ленивые загрузки:

public virtual TEntity GetById(object id) 
    { 
    return DbSet.Find(id); 
    } 

Я знаю, что метод Найти не поддерживает жадную загрузку, но, как можно модифицировать этот метод, чтобы использовать жадную загрузку, так что я использую этот метод следующим образом (для примера):

_unitOfWork.MyRepository.GetById(includeProperties: "Users"); 
+0

Попробуйте этот вопрос [включить-а-предикат-вдоль-с- included-properties] (http://stackoverflow.com/questions/28112285/how-can-i-include-a-predicate-along-with-included-properties) – JaredStroeb

ответ

3

Одним из возможных способов является использование FirstOrDefault с предикатом над DbSet с Include. Нетрудно построить вручную предикат с использованием метода Expression.Equal, но главная задача - получить имя свойства ключа. К счастью, мы можем использовать некоторые ObjectContext методы, чтобы сделать это, так что реализация может быть, как это (предполагая, что мы имеем доступ к конкретному DbContext экземпляра):

public virtual TEntity GetById(object id, params string[] includeProperties) 
{ 
    var propertyName = ((System.Data.Entity.Infrastructure.IObjectContextAdapter)DbContext).ObjectContext 
     .CreateObjectSet<TEntity>().EntitySet.ElementType.KeyMembers.Single().Name; 

    var parameter = Expression.Parameter(typeof(TEntity), "e"); 
    var predicate = Expression.Lambda<Func<TEntity, bool>>(
     Expression.Equal(
      Expression.PropertyOrField(parameter, propertyName), 
      Expression.Constant(id)), 
     parameter); 

    var query = DbSet.AsQueryable(); 
    if (includeProperties != null && includeProperties.Length > 0) 
     query = includeProperties.Aggregate(query, System.Data.Entity.QueryableExtensions.Include); 
    return query.FirstOrDefault(predicate); 
} 
+0

@ Иван, он работает отлично. Спасибо! – ruud

+0

здесь я получаю сообщение об ошибке: var propertyName = ((IObjectContextAdapter) Контекст) .ObjectContext .CreateObjectSet () .EntitySet.ElementType.KeyMembers.Single(). Name; «не удалось создать объект типа« System.Data.Entity.DbSet'1 [Model.ProductDetail] »для ввода« System.Data.Entity.Infrastructure.IObjectContextAdapter »." –

+0

@PranavMishra Процедура ожидает, что переменная 'Context' будет иметь тип класса DbContext (или производного). Пока полученная ошибка указывает на переменную типа 'DbSet '. –

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

  • Нет связанных вопросов^_^