使用预先加载的存储库通用方法GetById

时间:2016-09-07 14:11:23

标签: c# entity-framework repository repository-pattern

我正在使用Entity Framework,并希望在Repository类中创建通用的 GetById 方法并加载:

这是我使用延迟加载的方法:

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

我知道方法查找不支持预先加载,但是如何修改此方法以使用预先加载,以便我使用此方法如下(例如):

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

3 个答案:

答案 0 :(得分:3)

一种可能的方法是使用带有FirstOrDefault的{​​{1}}的{​​{1}}和谓词。使用command-line for Team Explorer Everywhere方法手动构建谓词并不困难,但主要的挑战是如何获取关键属性名称。幸运的是,我们可以使用一些DbSet方法来实现这一点,因此实现可能是这样的(假设我们可以访问具体的Include实例):

ObjectContext

答案 1 :(得分:0)

这是Entity Framework Core 2.0的更新。此外,此方法使用带有EF的新元数据属性自动获取第一级导航属性。

public virtual T Get(object id)
{
        var propertyName = "AddressId";

        //get all navigation properties defined for entity
        var navigationProps = _context.Model.FindEntityType(typeof(T)).GetNavigations();

        //turn those navigation properties into a string array
        var includeProperties = navigationProps.Select(p => p.PropertyInfo.Name).ToArray();

        //make parameter of type T
        var parameter = Expression.Parameter(typeof(T), "e");

        //create the lambda expression
        var predicateLeft = Expression.PropertyOrField(parameter, propertyName);
        var predicateRight = Expression.Constant(id);
        var predicate = Expression.Lambda<Func<T, bool>>(Expression.Equal(predicateLeft, predicateRight), parameter);

        //get queryable
        var query = _context.Set<T>().AsQueryable();

        //apply Include method to the query multiple times
        query = includeProperties.Aggregate(query, Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.Include);

        //return first item in query
        return query.FirstOrDefault(predicate);
}

答案 2 :(得分:0)

在存储库中使用它

public IQueryable<T> FindByCondition(Expression<Func<T, bool>> expression)
    {
        return this.RepositoryContext.Set<T>().Where(expression).AsNoTracking();
    }

和此有效方法

var User =  _IRepositoryWrapper.User.FindByCondition(x=>x.Id == id).Include(a=>a.Photos).FirstOrDefault();