C# 使用存储库模式,我们应该为DAL中的每个表或业务层中的对象定义类吗?

C# 使用存储库模式,我们应该为DAL中的每个表或业务层中的对象定义类吗?,c#,entity-framework,repository-pattern,C#,Entity Framework,Repository Pattern,当您有一个较大的数据库时,如何在c#with entity framework中正确实现存储库模式 我们应该在DAL(数据访问层)中为实现存储库接口的每个表定义类,还是在业务层中定义这样的对象 Repository<RetailerMarketplace> retailerMarketplaceRepo = null; Repository<Marketplace> marketplaceRepo = null; Repository<Product> pro

当您有一个较大的数据库时,如何在c#with entity framework中正确实现存储库模式

我们应该在DAL(数据访问层)中为实现存储库接口的每个表定义类,还是在业务层中定义这样的对象

Repository<RetailerMarketplace> retailerMarketplaceRepo = null;
Repository<Marketplace> marketplaceRepo = null;
Repository<Product> productRepo = null;
Repository<OP_FLAGS> opFlagsRepo = null;
Repository<RetailerMarketplaceAttributeMapping> retailerMPAttributesMappingRepo = null;
Repository<EbayVariation> ebayVariationRepo = null;
Repository<ProductIsListed> productIsListedRepo = null;
Repository<Skus_OpFlags> skusOpFlagsRepo = null;
Repository retailerMarketplaceRepo=null;
存储库marketplaceRepo=null;
存储库productRepo=null;
存储库opFlagsRepo=null;
Repository retailerMPAttributesMappingRepo=null;
存储库ebayVariationRepo=null;
存储库productIsListedRepo=null;
存储库skusOpFlagsRepo=null;

目前我已经定义了如上所述的对象,但我不清楚在DAL或业务层中定义和使用对象的正确方法是什么?

不要在业务层中创建任何
存储库
对象。您应该将工作单元模式与存储库模式一起使用。DAL应该有一个工作类单元,只将必要的存储库作为属性公开。这个工作类单元充当业务层和数据访问层之间的唯一网关

Repository<RetailerMarketplace> retailerMarketplaceRepo = null;
Repository<Marketplace> marketplaceRepo = null;
Repository<Product> productRepo = null;
Repository<OP_FLAGS> opFlagsRepo = null;
Repository<RetailerMarketplaceAttributeMapping> retailerMPAttributesMappingRepo = null;
Repository<EbayVariation> ebayVariationRepo = null;
Repository<ProductIsListed> productIsListedRepo = null;
Repository<Skus_OpFlags> skusOpFlagsRepo = null;
例如,假设我有两个实体
Foo
Bar
,结构如下:

public class Foo
{
    public int FooId { get; set; }
    public virtual ICollection<Bar> Bars { get; set; }
}

public class Bar
{
    public int BarId { get; set; }
    public int FooId { get; set; }
    public virtual Foo Foo { get; set; }
}
public class UnitOfWork
{
    private Repository<Foo> foos;

    public Repository<Foo> Foos
    {
        get
        {
            if(foos == null)
                foos = new Repository<Foo>();
            return foos;
        }
    }

    ...
}
就为每个实体定义存储库而言,您需要决定真正需要包括哪些实体。例如,我的
UnitOfWork
不包括
存储库
。也许我这样做是因为我可以通过它们关联的
Foo
上的链接属性访问所有
Bar
,而在我的域中单独查找
Bar
是没有意义的。一句话:这完全取决于您的域,您公开了哪些存储库。只要明智地选择


由ASP.NET/MVC团队编写,但其中的存储库/工作单元原则是使用实体框架的良好实践。无论您是否使用MVC,这都是一本很好的读物。

不要在您的业务层中创建任何
存储库
对象。您应该将工作单元模式与存储库模式一起使用。DAL应该有一个工作类单元,只将必要的存储库作为属性公开。这个工作类单元充当业务层和数据访问层之间的唯一网关

例如,假设我有两个实体
Foo
Bar
,结构如下:

public class Foo
{
    public int FooId { get; set; }
    public virtual ICollection<Bar> Bars { get; set; }
}

public class Bar
{
    public int BarId { get; set; }
    public int FooId { get; set; }
    public virtual Foo Foo { get; set; }
}
public class UnitOfWork
{
    private Repository<Foo> foos;

    public Repository<Foo> Foos
    {
        get
        {
            if(foos == null)
                foos = new Repository<Foo>();
            return foos;
        }
    }

    ...
}
就为每个实体定义存储库而言,您需要决定真正需要包括哪些实体。例如,我的
UnitOfWork
不包括
存储库
。也许我这样做是因为我可以通过它们关联的
Foo
上的链接属性访问所有
Bar
,而在我的域中单独查找
Bar
是没有意义的。一句话:这完全取决于您的域,您公开了哪些存储库。只要明智地选择


由ASP.NET/MVC团队编写,但其中的存储库/工作单元原则是使用实体框架的良好实践。无论您是否使用MVC,这都是一个很好的读物。

EF有内置的存储库对象,它们属于DbSet类型,EF会自行初始化。因此,在您的代码示例中,它们如下所示:

public DbSet<RetailerMarketplace> RetailerMarketplaces { get; set; }
public DbSet<Marketplace> MarketPlaces  { get; set; }
公共数据库集RetailerMarketplaces{get;set;} 公共数据库集市场{get;set;}
那么,为什么要有一个额外的存储库层呢

一个原因可能是能够伪造存储库对象,因为DbSet不提供可用于模拟或伪造的接口。例如,让我们从接口类型IRepostory创建一个通用存储库类。在本例中,类存储库将封装任何模型T的DbSet

public interface IRepository<T> where T : class
{
    void Add(T model);
    void Edit(T model);
    void Delete(T model);
    T Get(object id);
    IQueryable<T> List();
}

public class Repository<T> : IRepository<T> where T : class
{
    DatabaseContext context;
    DbSet<T> dbSet;

    public Repository(DatabaseContext context)
    {
        this.context = context;
        this.dbSet = context.Set<T>();
    }

    public void Add(T model)
    {
        dbSet.Add(model);
    }

    public void Edit(T model)
    {
        dbSet.Attach(model);
        context.Entry(model).State = EntityState.Modified;
    }

    public void Delete(T model)
    {
        if (context.Entry(model).State == EntityState.Detached)
        {
            dbSet.Attach(model);
        }
        dbSet.Remove(model);
    }

    public T Get(object id)
    {
        return dbSet.Find(id);
    }

    public IQueryable<T> List()
    {
        return dbSet;
    }
}
公共接口i假设,其中T:class
{
void-Add(T型);
无效编辑(T型);
无效删除(T型);
T Get(对象id);
IQueryable列表();
}
公共类存储库:IRepository,其中T:class
{
数据库上下文;
DbSet-DbSet;
公共存储库(数据库上下文)
{
this.context=上下文;
this.dbSet=context.Set();
}
公共空间添加(T型)
{
添加(模型);
}
公共无效编辑(T模型)
{
附加(模型);
context.Entry(model.State=EntityState.Modified;
}
公共作废删除(T型)
{
if(context.Entry(model.State==EntityState.Detached)
{
附加(模型);
}
删除(模型);
}
公共T获取(对象id)
{
返回dbSet.Find(id);
}
公共可查询列表()
{
返回dbSet;
}
}
实例化存储库

var context = new DbContext();
var repo = new Repository<Marketplace>(context);
var context=new DbContext();
var repo=新存储库(上下文);

上面的上下文是UoW对象。Repo是实例化的存储库对象。要创建假对象,您需要从IRepository派生。

EF有内置的存储库对象,它们属于DbSet类型,EF会自行初始化。因此,在您的代码示例中,它们如下所示:

public DbSet<RetailerMarketplace> RetailerMarketplaces { get; set; }
public DbSet<Marketplace> MarketPlaces  { get; set; }
公共数据库集RetailerMarketplaces{get;set;} 公共数据库集市场{get;set;}
那么,为什么要有一个额外的存储库层呢

一个原因可能是能够伪造存储库对象,因为DbSet不提供可用于模拟或伪造的接口。例如,让我们从接口类型IRepostory创建一个通用存储库类。在本例中,类存储库将封装任何模型T的DbSet

public interface IRepository<T> where T : class
{
    void Add(T model);
    void Edit(T model);
    void Delete(T model);
    T Get(object id);
    IQueryable<T> List();
}

public class Repository<T> : IRepository<T> where T : class
{
    DatabaseContext context;
    DbSet<T> dbSet;

    public Repository(DatabaseContext context)
    {
        this.context = context;
        this.dbSet = context.Set<T>();
    }

    public void Add(T model)
    {
        dbSet.Add(model);
    }

    public void Edit(T model)
    {
        dbSet.Attach(model);
        context.Entry(model).State = EntityState.Modified;
    }

    public void Delete(T model)
    {
        if (context.Entry(model).State == EntityState.Detached)
        {
            dbSet.Attach(model);
        }
        dbSet.Remove(model);
    }

    public T Get(object id)
    {
        return dbSet.Find(id);
    }

    public IQueryable<T> List()
    {
        return dbSet;
    }
}
公共接口i假设,其中T:class
{
void-Add(T型);
无效编辑(T型);
无效删除(T型);
T Get(对象id);
IQueryable列表();
}
公共类存储库:IRepository,其中T:class
{
数据库上下文;
DbSet-DbSet;
公共存储库