仓储模式:处理相同仓储的方法

3
我有四个非常相似但是具有层次结构的实体。每个实体都有一个对前一个实体的外键,并包含下一个实体的集合。

实体的一部分

现在,这些实体有四个相同的存储库:

存储库

这两种方法的实现会稍有不同。

是否有一种设计模式可以让我将所有四个实体合并为一个,同时允许我在需要时扩展功能

我尝试过这样做:

 public class DivisionRepository : IDivisionRepository
{
    private DbContext dbContext;
    private IDbSet<PrimaryDivision> primaryDivisionsEntitySet;
    private IDbSet<SecondaryDivision> secondaryDivisionsEntitySet;
    private IDbSet<TertiaryDivision> tertiaryDivisionsEntitySet;
    private IDbSet<QuaternaryDivision> quaternaryDivisionsEntitySet;

    public DivisionRepository(DbContext dbContext)
    {
        this.dbContext = dbContext;
        this.primaryDivisionsEntitySet = dbContext.Set<PrimaryDivision>();
        this.secondaryDivisionsEntitySet = dbContext.Set<SecondaryDivision>();
        this.tertiaryDivisionsEntitySet = dbContext.Set<TertiaryDivision>();
        this.quaternaryDivisionsEntitySet = dbContext.Set<QuaternaryDivision>();
    }

    public IDivision Find(Type type, object id)
    {
        if (type == typeof(PrimaryDivision))
        {
            return this.primaryDivisionsEntitySet.Find(id);
        } 
        else if (type == typeof(SecondaryDivision))
        {
            return this.secondaryDivisionsEntitySet.Find(id);
        }
        else if (type == typeof(TertiaryDivision))
        {
            return this.tertiaryDivisionsEntitySet.Find(id);
        }
        else if (type == typeof(QuaternaryDivision))
        {
            return this.quaternaryDivisionsEntitySet.Find(id);
        }

        throw new ArgumentException("The type provided was incorrect.");

}

CRUD操作的流程类似。

然而,它似乎并不是最优解决方案,因此我又回到了当前拥有的接口和类混合的杂糅状态(每个存储库有两个)。

谢谢


它们应该保持分离。关注点分离。单一职责原则。现在它们似乎密切相关,但将来谁知道呢。到那时,如果不进行大量重构和重写,可能就太晚分离它们了。 - rory.ap
这就像关于Entity Framework查询构建器的问题,是的,它可以做到...但是是否值得所有时间和精力,在大多数情况下并不值得。但是嘿,仍然是一个有趣的问题。 - Antoine Pelletier
1个回答

2
我会使用我所称的可组合仓库来实现这一点。
public static T SpecialFind(this IQueryable<T> entities, int id) where T: IDivision
{
    return entities.FirstOrDefault(x=>x.Id == id);
}

使用方法:
ctx.TertiaryDivisions.SpecialFind(1);

这样做的好处是,它提供了非常好的重用模式,特别是在更复杂的情况下。
但是,如果您绝对坚持使用存储库模式,则同样的基本原则适用:
public T Find<T>(object id) where T : IDivision
{
    return dbContext.Set<T>().Find(id);
}

你可以把这个通用的应用于整个仓库。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接