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

发布于 2024-10-08 05:35:05 字数 490 浏览 3 评论 0原文

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

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

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

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

正如您所看到的,我不确定整体架构,并且非常希望有一个基本的代码示例。

提前致谢!

I am working on a project following the suggested repository pattern in Steven Sanderson's excellent book "Pro ASP.NET MVC 2 Framework".

Take the following example: I have a table for "Products" and for "Images". Both have an own repository that creates a new DataContext in the constructor. Now, I want to establish a many-to-many relationship between the two entities called "ImagesForProducts".

Should I create a separate repository for the ImagesForProducts entities? If so, how can I share the DataContext between all the entities? In that case I have to instantiate my ProductController with two repositories (for Products and for ImagesForProducts), right?

I'd rather access the images using my product instances, so that I can write myProduct.AddImage(img). But how can I persist the relation in the database using the ProductRepository?

As you can see, I am not sure about the overall architecture and would highly appreciate a basic code example.

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

输什么也不输骨气 2024-10-15 05:35:05

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

我已经获得了一个 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();
    }
}

您对此解决方案有任何普遍的担忧吗?

After some careful research and consideration, I decided to let the repositories handle image attachments instead of the product instances (mostly because the instances shouldn't deal with any database related stuff).

I already got an ImagesForProducts entity because I am using Linq-to-SQL mapping. I therefore added a Table of that type to my product repository which I can initiate with the current DataContext of the product repository. That way, both instances always use a shared DataContext and I can simply implement a method "AttachImageToProduct" like this:

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

Do you have any general concerns about this solution?

罪#恶を代价 2024-10-15 05:35:05

存储库模式应用于表示域对象的内存存储。由于您希望域模型不了解持久性内部结构,并且所有内容都围绕聚合根设计,因此拥有 ImagesForProducts 实体是没有意义的,因此为 ImagesForProducts 实体拥有单独的存储库也是没有意义的。

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

一旦实现了管道,您就可以向产品添加图像:

product.Images.Add(image);

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

productRepository.Add(product);

The repository pattern should be used to represent an in-memory store for your domain objects. Since you want your domain model to be ignorant of the persistence internals and also have everything designed around aggregate roots, then it does not make sense to have a ImagesForProducts entity and thus doesn't make sense to have a separate repository for ImagesForProducts entities.

First of all I Would recommend building your domain model with POCO objects that can be used in any persistence scenario (LINQ to SQL, EF, Stored Procedures..).
You should have only two repositories (ProductRepository and ImageRepository) and resolve the many to meny relation as "relational" properties in both domain objects. For example you can add an Image collection to the Product domain object and a Product collection to the Image domain object. Once you build your POCO objects, then you can handle mappings to the specific persistence store inside your repositories (preferrably in the constructor).

Once you implement the plubming, you can and add an image to the product:

product.Images.Add(image);

Then you can call your repository like this:

productRepository.Add(product);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文