实体框架存储库模式 - 数据库目录

时间:2014-04-20 17:35:59

标签: entity-framework entity-framework-4 repository-pattern unit-of-work

我已将Repository Pattern和Unit of Work实现到我的ASP.NET Web API项目中。

它运作良好。现在有一个问题告诉我一个可以处理我的应用程序中所有关于设置目录的存储库。

现在我必须在我的工作单元中创建所有公共存储库,这些公共存储库引用如下所示的EF实体:

public IRepository<Document> Document { get { return GetStandardRepo<Document>(); } }

文档是EF实体。 IRepository实现以下方法:

public interface IRepository<T> where T : class
    {
        IQueryable<T> GetAll();
        IQueryable<T> GetAllReadOnly();
        T GetById(int id);
        void Add(T entity);
        void Update(T entity);
        void Delete(T entity);
        void Delete(int id);
    }

我的数据库中有大约20个表设置目录,所以如果我遵循这个模式,我将不得不创建20:

public IRepository<SetupEmployeeType> Document { get { return GetStandardRepo<SetupEmployeeType>(); } }
public IRepository<SetupMaritalStatus> Document { get { return GetStandardRepo<SetupMaritalStatus>(); } }
public IRepository<SetupRelationshipCode> Document { get { return GetStandardRepo<SetupRelationshipCode>(); } }
public IRepository<SetupLocationType> Document { get { return GetStandardRepo<SetupLocationType>(); } }
.....
.....

我想的一个解决方案是创建我自己的自定义IRepository实现,可能是ICatalogRepository,如下所示:

 public class CatalogRepository : EFRepository<EF Entity>, ICatalogRepository
        {
            public CatalogRepository (DbContext context) : base(context) { }


            public IEnumerable<SetupEmployeeType> GetEmployeeTypes()
            {
                var catalog = DbContext
                    .Set<SetupEmployeeType>()
                    .ToList();

                return catalog;

            }

public IEnumerable<SetupMaritalStatus> GetMaritalStatus()
            {
                var catalog = DbContext
                    .Set<SetupMaritalStatus>()
                    .ToList();

                return catalog;

            }
        }

我的问题是 CatalogRepository 必须继承自 EFRepository ,但 T 不仅仅是一个实体,因为我将从不同的方法返回不同的实体

这是正确的方法吗?

1 个答案:

答案 0 :(得分:0)

是的,不要使用这种反模式(在暴露EF实体的同时包装DbContext的通用存储库)。如果你真的想使用Repository,那么存储库接口只返回business(或查看模型,如果它是一个查询repo)对象,永远不会IQueryable或其他细节暴露EF或你正在使用的任何东西。

简单地为您的需求创建一个存储库,忘记一般的东西它是一种反模式。所以你的CatalogRepository将使用一个DbContext来发出所需的所有查询,然后从结果中组装一个视图模型/业务对象并返回它。

该应用程序只会知道Repo,而不是EF。查询将保持在DAL级别(不在您的应用程序/服务/控制器中),并且您的应用程序将被解除关联,尊重分离。

包装DbContext的类最多是无用的(它带来了什么价值?),最糟糕的是漏洞抽象。如果您想直接使用EF实体和EF,请直接使用EF,让您的生活更轻松。如果你想将应用程序的其余部分与持久性细节分离(注意我已经说过持久性,而不是rdbms)正确使用Repository。但是,不要因为你有一个名为repository的类而自欺欺人地使用Repository模式。您应该确切地知道为什么使用模式以及它为您的情况带来了哪些好处。如果你不明白为什么,这不是最好的做法。