Шаблон репозитория с Linq to SQL: отношения «многие ко многим» - PullRequest
2 голосов
/ 18 декабря 2010

Я работаю над проектом, следуя предложенному шаблону хранилища в превосходной книге Стивена Сандерсона "Pro ASP.NET MVC 2 Framework".

Возьмите следующий пример: у меня есть таблица для «Продукты» и «Изображения».Оба имеют собственный репозиторий, который создает новый DataContext в конструкторе.Теперь я хочу установить связь «многие ко многим» между двумя сущностями, называемыми «ImagesForProducts».

Должен ли я создать отдельный репозиторий для сущностей ImagesForProducts?Если так, как я могу разделить DataContext между всеми объектами?В этом случае мне нужно создать экземпляр моего ProductController с двумя репозиториями (для продуктов и для ImagesForProducts), верно?

Я бы предпочел получить доступ к изображениям с помощью экземпляров моего продукта, чтобы я мог написать myProduct.AddImage (img).Но как я могу сохранить отношение в базе данных, используя ProductRepository?

Как вы можете видеть, я не уверен в общей архитектуре и был бы очень признателен за базовый пример кода.

Спасибо зазаранее!

Ответы [ 2 ]

1 голос
/ 26 января 2011

После тщательного изучения и рассмотрения я решил позволить репозиториям обрабатывать вложения изображений вместо экземпляров продукта (в основном потому, что экземпляры не должны иметь дело с какими-либо вещами, связанными с базой данных).

Я уже получилСущность 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 голосов
/ 13 января 2011

Шаблон репозитория должен использоваться для представления хранилища в памяти для ваших доменных объектов.Поскольку вы хотите, чтобы ваша доменная модель не учитывала внутренние компоненты персистентности, а также имела все, спроектированное вокруг агрегированных корней, то нет смысла иметь сущность ImagesForProducts и, следовательно, не имеет смысла иметь отдельный репозиторий для сущностей ImagesForProducts.

Прежде всего, я бы порекомендовал построить модель вашего домена с использованием объектов POCO, которые можно использовать в любом постоянном сценарии (LINQ to SQL, EF, хранимые процедуры ...).Вы должны иметь только два репозитория (ProductRepository и ImageRepository) и разрешить отношение «многие ко многим» как «реляционные» свойства в обоих объектах домена.Например, вы можете добавить коллекцию Image в объект домена Product и коллекцию Product в объект домена Image.Как только вы создадите свои объекты POCO, вы сможете обрабатывать сопоставления с определенным хранилищем сохраняемости в своих хранилищах (предпочтительно в конструкторе).

Как только вы реализуете plubming, вы можете добавить изображение к продукту:

product.Images.Add(image);

Затем вы можете назвать свой репозиторий следующим образом:

productRepository.Add(product);
...