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



当您拥有更大的数据库时,如何使用实体框架在c#中正确实现存储库模式?

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

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;

目前我已经定义了如上所述的对象,但我很困惑定义对象并在DAL或业务层中使用它们的正确方法是什么?

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

例如,假设我有两个实体FooBar,其结构如下:

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; }
}

我的UnitOfWork类可能如下所示:

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

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

本文由ASP编写。NET/MVC团队,但其中的存储库/工作单元原则是使用实体框架的任何东西的良好实践。无论你是否使用MVC,这都是一本不错的读物。

EF有内置的存储库对象,它们的类型为DbSet,EF会自行初始化。所以在你的代码示例中,它们会像:

public DbSet<RetailerMarketplace> RetailerMarketplaces { get; set; }
public DbSet<Marketplace> MarketPlaces  { get; set; }

那么,为什么要有一个额外的存储库层呢?

其中一个原因可能是能够伪造存储库对象,因为DbSet没有提供可用于模拟或伪造的接口。例如,让我们从IRepostory的接口类型创建一个通用存储库类。在这种情况下,类Repository将为任何模型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;
}
}

实例化存储库

var context = new DbContext();
var repo = new Repository<Marketplace>(context);

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

最新更新