2010-12-18 63 views
2

我正在研究Steven Sanderson的优秀书籍“Pro ASP.NET MVC 2 Framework”中建议的存储库模式之后的项目。Linq to SQL的存储库模式:多对多关系

请看下面的例子:我有一个表格用于“Products”和“Images”。两者都有一个自己的存储库,在构造函数中创建一个新的DataContext。现在,我想建立名为“ImagesForProducts”的两个实体之间的多对多关系。

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

我宁愿使用我的产品实例访问图像,以便我可以编写myProduct.AddImage(img)。但是,如何使用ProductRepository将关系保存在数据库中?你可以看到,我不确定整个架构,并且非常感谢一个基本的代码示例。

在此先感谢!

回答

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

你有关于这个解决方案的任何普遍关注的问题?

0

存储库模式应该用来表示您的域对象的内存存储。既然你希望你的领域模型不了解持久化内部结构,并且还有一些围绕聚合根的设计,那么就没有必要拥有一个ImagesForProducts实体,因此对ImagesForProducts实体有一个单独的存储库是没有意义的。

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

一旦你实现plubming,你可以和图像添加到产品:

product.Images.Add(image); 

然后,你可以打电话给你的资料库是这样的:

productRepository.Add(product); 
+0

感谢您的回答。 Linq mapper已经为我提供了一个ImagesForProducts实体,这个实体并不关心我,因为它只会用在Linq相关的仓库中,并且对我的模型来说并不实质。正如你在我的回答中所看到的,最终我决定不使用产品实例添加图像。这样,我的“真实”模型实体与数据库相关的东西没有任何关系。 – Shackles 2011-01-26 16:08:41