c# - 使用包含检索实体的通用存储库和 Entity Framework 逻辑

标签 c# entity-framework-5

我有两个 Entity Framework 5执行 (i) 单个实体的 Get() 方法通过 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) 方法编写逻辑的建议的帮助将不胜感激。

最佳答案

首先,为实体写一个基类,定义主键字段。像下面这样的东西可能会起作用:

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 中是否还有其他方法。

关于c# - 使用包含检索实体的通用存储库和 Entity Framework 逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11948288/

相关文章:

entity-framework - EntityFramework:如何配置级联删除以使外键无效

c# - 在 c# 控制台应用程序中启动 2 个 DBContext 对象,一个用于日志,另一个用于业务数据

c# - 如何查看 LINQ 发送到我的数据库的 SQL 文本?

javascript - 将 C# 函数返回值传递给 Javascript

c# - 在 .Net Core 中禁用模型绑定(bind)器

c# - 如何将复杂的二进制 Perl 正则表达式转换为 C# 或 PowerShell?

c# - Entity Framework 5.0 复杂对象的 SaveChanges

c# - EXE 未运行,配置意外更改?

C# 只替换文件中的一个东西

entity-framework - 面向 .NET 4.5 后,EF 数据注释不是 "working"