使用Linq to SQL的存储库模式:多对多关系

时间:2010-12-18 11:58:16

标签: linq-to-sql many-to-many repository-pattern

我正在按照Steven Sanderson的优秀书籍“Pro ASP.NET MVC 2 Framework”中的建议存储库模式开展一个项目。

采用以下示例:我有一个“产品”和“图像”表。两者都有自己的存储库,可以在构造函数中创建新的DataContext。现在,我想在名为“ImagesForProducts”的两个实体之间建立多对多关系。

我应该为ImagesForProducts实体创建一个单独的存储库吗?如果是这样,我如何在所有实体之间共享DataContext?在这种情况下,我必须使用两个存储库(对于Products和ImagesForProducts)实例化我的ProductController,对吧?

我宁愿使用我的产品实例访问图像,以便我可以编写myProduct.AddImage(img)。但是如何使用ProductRepository在数据库中保持关系?

正如您所看到的,我不确定整体架构,并非常欣赏基本代码示例。

提前致谢!

2 个答案:

答案 0 :(得分:1)

经过一些仔细的研究和考虑,我决定让存储库处理图像附件而不是产品实例(主要是因为实例不应该处理任何与数据库相关的东西)。

我已经有了一个ImagesForProducts实体,因为我正在使用Linq-to-SQL映射。因此,我将该类型的表添加到我的产品库中,我可以使用产品存储库的当前DataContext启动它。这样,两个实例总是使用共享的DataContext,我可以简单地实现一个方法“AttachImageToProduct”,如下所示:

public class MsSqlProductsRepository : MsSqlRepository<Product>, IProductsRepository
{
    protected Table<ImagesForProducts> imageRelationsTable { get; set; }

    public MsSqlProductsRepository(string connectionString)
        : base(connectionString)
    {
        imageRelationsTable = DataContext.GetTable<ImagesForProducts>();
    }

    public void AttachImageToProduct(Image image, Product product)
    {
        if (imageRelationsTable.First(r => r.ImageId == image.Id && r.ProductId == product.Id) != null)
            return;

        ImagesForProducts rel = new ImagesForProducts();
        rel.ImageId = image.Id;
        rel.ProductId = product.Id;

        imageRelationsTable.InsertOnSubmit(rel);
        entitiesTable.Context.SubmitChanges();
    }
}

您对此解决方案有任何普遍关注吗?

答案 1 :(得分:0)

存储库模式应该用于表示域对象的内存存储。由于您希望您的域模型不知道持久性内部,并且还有围绕聚合根设计的所有内容,因此拥有ImagesForProducts实体没有意义,因此为ImagesForProducts实体创建单独的存储库没有意义。

首先,我建议使用可在任何持久性场景中使用的POCO对象构建域模型(LINQ to SQL,EF,Stored Procedures ..)。 您应该只有两个存储库(ProductRepository和ImageRepository),并将多个与meny关系解析为两个域对象中的“关系”属性。例如,您可以将Image集合添加到Product域对象,将Product集合添加到Image域对象。一旦构建了POCO对象,就可以处理存储库中特定持久性存储的映射(最好是在构造函数中)。

实施插件后,您可以将图像添加到产品中:

product.Images.Add(image);

然后您可以像这样调用您的存储库:

productRepository.Add(product);