实体框架:使用通用存储库从多个实体检索数据

时间:2018-09-27 21:10:54

标签: c# asp.net-web-api repository

我创建了一个Web API项目,其中正在实现一个存储库模式。简而言之,我具有以下结构。

Controller
    |
Business/Service Layer
    |
Repository
    |
DB-Access

这是我的服务层之一的代码:

public class DashboardService : IDashboardService
{   
    private readonly IRepository<USERROLE> repoUserRole;
    private readonly IRepository<ROLEEXT> repoRoleExt;  

    public void GetUserInstitution(string UserId)
    {
        repoUserRole.GetList(x => x.ID == UserId, null).Join(
            repoRoleExt.GetList(),
            uRole => uRole.ROLEID, roleEx => roleEx.ROLEID, (uRole, roleEx) => new
            {
                USERROLE = uRole,
                ROLEEXT = roleEx
            }).ToList();
    }
}

GetList存储库中的方法如下:

public class Repository<T> : IRepository<T> where T : class, new()
{
    // Some code omitted
    public IEnumerable<T> GetList()
    {
        return DbSet.ToList();
    }

    public IEnumerable<T> GetList(Expression<Func<T, bool>> predicate, params string[] navigationProperties)
    {
        IEnumerable<T> list;
        var query = DbSet.AsQueryable();
        if (navigationProperties != null && navigationProperties.Length > 0)
        {
            foreach (string navigationProperty in navigationProperties)
            {
                query = query.Include(navigationProperty);
            }
        }
        list = query.Where(predicate).ToList<T>();
        return list;
    }
}

我想要的:

  • 一个通用方法,该方法可以采用多个实体(加入它们)并返回结果集。 (这种方法也应该在哪里?(业务或回购)

从我的代码中可以看出,我遵循以下方法:

  • 创建每个存储库的实例<=>实体类型对象
  • 使用这些对象检索数据

问题:

  • 不确定这是否是实现存储库模式的正确方法!
  • 如果不是,最好的处理方式是什么?

P.S .:我知道GetUserInstitution方法中存在错误。

编辑 :而且,如果不使用通用存储库,是否必须基于实体创建多个存储库?

1 个答案:

答案 0 :(得分:0)

您应该真正考虑只为每个实体创建具有不同合同的独立存储库,而不要尝试创建通用存储库。并非您的所有存储库都需要返回列表,并且没有实现不具有方法样板的仓库的NotImplementedExceptions之类的东西也没有意义。 相反,请按照我的许多工程师采用的方法为每个存储库创建单独的合同/接口。 似乎创建一个通用存储库将遵循SRP规则,但是在开始创建越来越多的存储库之后,您将开始看到存储库的某些特有属性,最后,如果没有通用存储库,您会更好。

为存储库类创建接口的一种情况如下

public interface IRepository<T> where T : IAggregateRoot

然后,您将其用作

    public interface IOrderRepository : IRepository<Order>
{
Order Add(Order order);
// ...
}
上面的

IAggregateRoot是标记界面模式。

老实说,我会从每个存储库开始使用不同的合同,然后在以后添加IRepository的情况下这样做。