我的数据库中有几个产品表:
我现在看到它的方式,我可以制作具有以下方法的IProduct:
或者,我可以将每个分开来模仿表结构:IProductType,IProductCategory等。
是否有理由选择一个而不是另一个?
答案 0 :(得分:13)
存储库的想法是委托每个人负责一个实体。在这种情况下,建议为每个实体建立一个存储库。您也可以使用大型存储库,但这不是最佳解决方案。最后,你会得到一个有很多方法的巨大课程,而且非常紧密。也难以维修。
答案 1 :(得分:6)
我认为拥有一个庞大的存储库并不是一个好主意,那么你基本上就拥有一个可以完成所有工作的数据访问神类。
我希望有一个基础Repository<T>
来执行常见操作,例如GetById
和GetAll
。我通常都有我的所有存储库继承这个基类以获得免费的常用方法,所以我不必继续重写相同的代码。
答案 2 :(得分:4)
在我看来,这在很大程度上取决于业务领域模型,确定您的主要业务实体是非常重要的。数据库中的每个表都不一定直接映射到业务实体。表只是关系数据库的规范化方式中一个或多个实体的表示。
尝试将您的域模型描绘成超出规范化关系数据库的限制,是否真的有多个业务概念?存储库应围绕固体,整体,一流的业务实体构建。
我的建议是拥有一个IProductRepository,其中包含实现CRUD操作的必要方法,并根据需要进行扩展。您不希望得到过于雄心勃勃的界面,因为您可能不需要大部分界面,这可能是一种负担。接口的重要一点是将代码与持久性模式分离,因此后者可以灵活地在它们之间切换。
也许在未来,企业需要发展到更详细的代表 - 例如 - 产品的供应商,在那一刻,您将使用您的良好判断来决定代表一个重要的商业实体,值得一个专用存储库与否。
希望这有帮助。
答案 3 :(得分:3)
我不赞同其他人(编辑:除了艾萨克)。小型存储库是一个外观(不是模式)。
如果实体类型是耦合的(彼此具有导航属性),那么它们实际上是不可分离的。
修改一个实体类型并提交更改可能会将更改提交给其他实体。
此外,您无法在同一工作单元上创建任何小型存储库, 因为ORM只有有限数量的实体映射到数据库。
将您的模型划分为可分离的域,并为每个域创建一个特定的工作单元。
在这些工作单元上,为您可能需要立即访问的每种实体类型创建aggregate roots。
每个root都应该有特定类型的add,remove,getbykeys,query等方法。
工作单元应该有commit更改和相似的方法。
每个根类似于其他人提到的小型存储库,但是,工作单元是真正的中型存储库(其模型可能有多种类型)。
示例:
// Create one of these
interface IUnitOfWork
{
void Commit();
}
// Create one of these
interface IEntitySet<TEntity> where TEntity : class
{
void Add(TEntity entity);
void Remove(TEntity entity);
TEntity Create<TSpecificEntity>() where TSpecificEntity : TEntity;
IQueryable<TEntity> Query();
}
// Create one of these per entity type
interace IEntitySetOfTEntity1 : IEntitySet<Entity1>
{
TEntity1 GetByKeys(int key1);
}
interace IEntitySetOfTEntity2 : IEntitySet<Entity2>
{
TEntity1 GetByKeys(short key1, short key2);
}
// Create one of these per separatable domain
interface IDomain1UnitOfWork : IUnitOfWork
{
IEntitySetOfTEntity1 Entity1s
{
get;
}
IEntitySetOfTEntity2 Entity2s
{
get;
}
}
所有这些接口及其实现都可以自动生成。
这些接口及其实现的重量非常轻,绝不是“具有大量方法的巨大类”。由于它们可以自动生成,因此维护很容易。
具体功能可以通过以下方式添加到接口IDomain1UnitOfWork,IEntitySetOfTEntity1等中:
一个。扩展方法
湾部分接口和类(不太推荐,因为这会导致DAL不太清晰)
如果使用扩展方法将GetByKeys()方法添加到IEntitySet&lt; Entity1&gt;中,则可以忽略IEntitySetOfTEntity1之类的接口。