扩展(替代)存储库设计模式?

Extending (alternative to) the repository desing pattern?

我正在使用 ASP.NET MVC 开发一个项目。我想在应用程序的数据访问层和业务逻辑层之间创建一个抽象层。我一直在使用存储库和工作单元。回顾一下,在此模式中,创建了一个通用存储库和许多特定存储库。我在这个项目中遇到的问题是我需要另一个存储库中某个特定存储库的方法。例如,我有一个产品和子产品存储库。我想在 Product 方法中使用 Subproduct 方法,而不是每次都为 Subproduct 重写 LINQ 查询。有什么方法可以扩展存储库设计模式的功能,或者我必须使用其他设计模式?

public class ProductSubcategoryRepository : Repository<ProductSubcategory>, IProductSubcategoryRepository
{
    public ProductSubcategoryRepository(DbContext context) : base(context)
    {
    }

    public IEnumerable<ProductSubcategory> CheckSomeCondition()
    {
        // LINQ to check some condition based on product subcategory
    }
}

public class ProductCategoryRepository : Repository<ProductCategory>, IProductCategoryRepository
{
    public ProductCategoryRepository(DbContext context) : base(context)
    {

    }

    public IEnumerable<ProductCategory> GetProductCategoriesBeforeDate()
    {
        // Repeated LINQ to check some condition based on product subcategory 
        // (I am looking for a way to call the same method of ProductSubCategory calss)

        // LINQ To return List of product category if the previous query is true
    }
}

最直接的方法是让 ProductCategoryRepository 在其构造函数中创建一个 ProductSubcategoryRepository 的实例:

public class ProductCategoryRepository : Repository<ProductCategory>, IProductCategoryRepository
{
    private ProductSubcategoryRepository subRepo;
    public ProductCategoryRepository(DbContext context) : base(context)
    {
        subRepo = new ProductSubcategoryRepository(context);
    }

    public IEnumerable<ProductCategory> GetProductCategoriesBeforeDate()
    {
        // call subRepo
    }
}

如果您已经有一个 ProductSubcategoryRepository 的实例,您可以注入它:

public ProductCategoryRepository(DbContext context, ProductSubcategoryRepository subRepo) : base(context)
{
    this.subRepo = subRepo;
}

您已经在您的问题中说过您拥有适当的业务逻辑层。那是管理这些东西的最佳位置。

因此,您不会在另一个存储库中调用一个存储库。相反,您可以通过 BLL 的一种方法调用两个存储库来实现目标。希望您的 UoW 暴露于 BLL。这样,在相同的 UoW 范围内,您可以执行这两个操作。

这不仅限于Get记录。这可以进一步扩展为 Get-Modify-Update 或其他。

我不确定你的 CheckSomeCondition 是做什么的。它只是一个 Predicate 就可以了。如果它是某些业务逻辑的一部分,更好的方法是如上所述将其转移到 BLL。