通用存储库&使用包含检索实体的实体框架逻辑

时间:2012-08-14 08:13:09

标签: c# entity-framework-5

我有两个Entity Framework 5 Get()方法执行(i)单个实体获取ID,(ii)单个实体获取通过一个过滤器,任何急切的装载用螺栓固定。请参阅下面的代码:

internal readonly FallenNovaContext Context;
private readonly DbSet<TEntity> _dbSet;

internal GenericRepository(FallenNovaContext context)
{
    Context = context;
    _dbSet = context.Set<TEntity>();
}

// (i) Get by ID.
public TEntity GetById(int id)
{
    return _dbSet.Find(id);
}

// (ii) Get by filter and optional eager loading includes.
public TEntity Get(
    Expression<Func<TEntity, bool>> filter = null,
    IEnumerable<string> includePaths = null)
{
    IQueryable<TEntity> query = _dbSet;

    if (filter != null)
    {
        query = query.Where(filter);
    }

    if (includePaths != null)
    {
        query = includePaths.Aggregate(query, (current, includePath) => current.Include(includePath));
    }

    return query.SingleOrDefault();
}

现在所有这些工作正常我在我的应用程序增长时发现的是我编写了许多需要两者混合的非泛型方法 - 更具体地说,我希望通过ID获得泛型并且还能够加载相关的实体。

所以方法签名看起来像这样:

 public TEntity GetById(
     int id,
     IEnumerable<string> includePaths)
 {
       // ???
 }

我可以这样称呼:

 User user = UnitOfWork.UserRepository.GetById(117, new List<string>() { "UserRole", "UserStatus" });

或者像这样:

 Car car = UnitOfWork.CarRepository.GetById(51, new List<string>() { "Make", "Model", "Tyres" });

有关如何使用Entity Framework 5编写 TEntity GetById(int id,IEnumerable includePaths) 方法的逻辑的建议的任何帮助将不胜感激。< / p>

1 个答案:

答案 0 :(得分:2)

首先,为实体编写基类,定义主键字段。以下内容可能有效:

public abstract class BaseEntity
{
    public int Id {get;set;}
}

然后,为您的存储库编写基类;定义此基本存储库中的所有泛型方法。让此存储库具有实体类型的通用参数:

public class RepositoryBase<TEntity> where TEntity : BaseEntity
{
   public TEntity GetById(
     int id,
     params Expression<Func<TEntity, object>>[] includeList)
     {
            TEntity entity = null;
            ObjectQuery<TEntity> itemWithIncludes = context.Set<TEntity>() as ObjectQuery<TEntity>;
            foreach (Expression<Func<TEntity, object>> path in includeList)
            {
                itemWithIncludes = ((IQueryable)itemWithIncludes.Include(path)) as ObjectQuery<T>;
            }

            IQueryable<TEntity> items = itemWithIncludes.AsQueryable<TEntity>();
            entity = items.Where(p => p.Id == id).SingleOrDefault();
            return entity;
     }
}

更新:@Bern询问是否有其他方法可以找到主键而不是声明基类。以下问题涉及此问题。

Entity Framework 4: How to find the primary key?

Entity Framework code first. Find primary key

另一方面,我不知道EF 5中是否还有其他方式。