【问题标题】:Repository Pattern: Dealing with Identical Repositories存储库模式:处理相同的存储库
【发布时间】:2016-10-26 09:59:42
【问题描述】:

我有四个非常相似但层次分明的实体。每一个都有一个前一个的外键,并包含下一个的集合。

Part of entity

目前,这些实体有四个相同的存储库:

Repository

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

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

我尝试过这样做:

 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 操作以类似的方式继续。

但是,它似乎不是最理想的解决方案,所以我回到了我现在拥有的接口和类的大杂烩(每个存储库两个)。

谢谢

【问题讨论】:

  • 它们应该保持分开。关注点分离。单一责任主体。现在他们似乎密切相关,但在未来,谁知道呢。到那时,如果不进行大量重构和重写就将它们分开可能为时已晚。
  • 这就像关于实体框架查询构建器的问题,是的,它可以完成......但是值得所有的时间和精力,在大多数情况下它不是。但是,嘿,这仍然是一个有趣的问题。

标签: c# entity-framework repository


【解决方案1】:

我会使用我所谓的composable repository 来做到这一点。

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

或者,您可以将泛型放在整个存储库中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-19
    • 1970-01-01
    • 2023-04-10
    相关资源
    最近更新 更多