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

Entity framework 实体框架存储库模式-数据库目录,entity-framework,entity-framework-4,repository-pattern,unit-of-work,Entity Framework,Entity Framework 4,Repository Pattern,Unit Of Work,我已经在我的ASP.NETWebAPI项目中实现了存储库模式和工作单元 它工作得很好。现在有一个问题向我提出,关于一个可以处理我的应用程序中所有设置目录的存储库 现在,我必须在我的工作单元中创建所有引用EF实体的公共存储库,如下所示: public IRepository<Document> Document { get { return GetStandardRepo<Document>(); } } public class CatalogRepository :

我已经在我的ASP.NETWebAPI项目中实现了存储库模式和工作单元

它工作得很好。现在有一个问题向我提出,关于一个可以处理我的应用程序中所有设置目录的存储库

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

public IRepository<Document> Document { get { return GetStandardRepo<Document>(); } }
 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;

            }
        }
public IRepository文档{get{return GetStandardRepo();}
其中,文档是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);
    }
公共接口i假设,其中T:class
{
IQueryable GetAll();
IQueryable GetAllReadOnly();
T GetById(int-id);
无效添加(T实体);
无效更新(T实体);
无效删除(T实体);
无效删除(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>(); } }
.....
.....
public IRepository文档{get{return GetStandardRepo();}
公共IRepository文档{get{return GetStandardRepo();}}
公共IRepository文档{get{return GetStandardRepo();}}
公共IRepository文档{get{return GetStandardRepo();}}
.....
.....
我想的一个解决方案是创建我自己的自定义IRepository实现,可能类似于下面的iCatalOpository:

public IRepository<Document> Document { get { return GetStandardRepo<Document>(); } }
 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;

            }
        }
公共类目录存储库:eRepository、ICatalogRepository
{
公共目录存储库(DbContext上下文):基(上下文){}
公共IEnumerable GetEmployeeTypes()
{
var catalog=DbContext
.Set()
.ToList();
退货目录;
}
公共IEnumerable GetMaritalStatus()
{
var catalog=DbContext
.Set()
.ToList();
退货目录;
}
}
我的问题是,CatalogRepository必须从eRepository继承,但是T不仅仅是一个实体,因为我将从不同的方法返回不同的实体


这是正确的方法吗?

是的,不要使用这种反模式(在公开EF实体时通用存储库包装DbContext)。如果确实要使用存储库,请使存储库接口仅返回业务(或视图模型,如果是查询repo)对象,而不要返回IQueryable或其他详细信息,以公开EF或您正在使用的任何内容

简单地说,为您的需要创建一个存储库,忘记一般的东西——这是一种反模式。因此,CatalogRepository将使用DbContext来发出所有需要的查询,然后根据结果组装视图模型/业务对象并返回该结果

应用程序将只知道回购协议,而不知道EF。查询将保持在DAL级别(不在您的应用程序/服务/控制器中),并且您的应用程序是解耦的,关注点分离得到尊重

包装DbContext的类充其量是无用的(它带来了什么价值?),充其量是泄漏的抽象。如果您想直接使用EF实体和EF,请直接使用EF。如果您想将应用程序的其余部分与持久性细节分离(注意,我说的是持久性,而不是rdbms),请正确使用存储库。但不要自欺欺人,因为您有一个名为Repository的类,所以使用了Repository模式。您应该确切地知道为什么要使用模式,以及它给您的情况带来了什么好处。如果你不明白为什么,这不是最佳实践