简体   繁体   English

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

[英]Entity Framework: Retrieve data from multiple entities using generic repository

I have created a Web API Project in which I am implementing a repository pattern. 我创建了一个Web API项目,其中正在实现一个存储库模式。 In a nutshell, I have the following structure. 简而言之,我具有以下结构。

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

Here is a code of one of my Service Layer: 这是我的服务层之一的代码:

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 Method in Repository looks like this: 存储库中的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;
    }
}

What I want: 我想要的是:

  • A Generic method which can take multiple entities(join them) and return the resultset. 一个通用方法,可以采用多个实体(加入它们)并返回结果集。 (Also where should that method be? (Business or Repo) (这种方法也应该在哪里?(业务或回购)

As seen in my code I have followed the following approach: 从我的代码中可以看出,我遵循以下方法:

  • Create Instance of Each Repository <=> Entity type object 创建每个存储库<=>实体类型对象的实例
  • Using those objects retrieve data 使用这些对象检索数据

Problem: 问题:

  • Not sure if this is a correct approach of implementing the repository pattern! 不确定这是否是实现存储库模式的正确方法!
  • If not What would be the best way to handle this? 如果不是,最好的方法是什么?

PS: I am aware of error present in the GetUserInstitution method. PS:我知道GetUserInstitution方法中存在错误。

Edit : Also, If not using Generic repository, do I have to create multiple repository based on Entites? 编辑 :另外,如果不使用通用存储库,是否必须基于实体创建多个存储库?

You should really consider just creating separate repositories with separate different contracts for each entity and not resort to trying to create a generic repository. 您应该真正考虑只为每个实体创建具有不同合同的独立存储库,而不要尝试创建通用存储库。 Not all of your repositories will NEED to return a list, and it doesnt make sense to have repositories that dont implement methods to have boilerplate NotImplementedExceptions or things like that. 并非您的所有存储库都需要返回列表,并且没有实现不具有方法样板的仓库的NotImplementedExceptions之类的东西也没有意义。 Instead, follow the approach taken my many engineers of just creating separate contracts/interfaces for each repository. 相反,请按照我的许多工程师采用的方法为每个存储库创建单独的合同/接口。 It may appear that creating a single generic repository would be following the SRP rule, but after you begin creating more and more repositories, youll begin to see some idiosyncratic attributes of the repositories, and in the end your just better of without generic repository. 似乎创建一个通用存储库将遵循SRP规则,但是在开始创建越来越多的存储库之后,您将开始看到存储库的某些特有属性,最后,如果没有通用存储库,您会更好。

One case for creating an interface for a repository class is as follows 为存储库类创建接口的一种情况如下

public interface IRepository<T> where T : IAggregateRoot

Then, you would use it as 然后,您将其用作

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

IAggregateRoot above is the marker interface pattern. 上面的IAggregateRoot是标记界面模式。

Honestly, I would just start out with different contracts per repository, and later if it makes sense to add the IRepository, do so. 老实说,我只是从每个存储库的不同合同开始,然后在以后添加IRepository的情况下这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM