Как использовать Процедуры магазина и Сложные типы, используя Шаблон репозитория в EF? - PullRequest
9 голосов
/ 23 января 2012

Как мы можем использовать процедуры хранения и сложные типы при работе с шаблоном репозитория в Entity Framework? Кто-нибудь может привести простой пример.

Кроме того, в какой ситуации мы должны на самом деле использовать шаблон репозитория?

Заранее спасибо

Ответы [ 2 ]

14 голосов
/ 23 января 2012

Я думаю, вы упустили момент, когда люди реализуют шаблон хранилища, когда EF уже реализует шаблон хранилища через ObjectSet / DbSet?

Популярный ответ будет, потому что многие учебники советуют использовать его без объяснения причин. Есть веские причины не использовать Уровень репозитория поверх ObjectSet / DbSet. Однако я укажу несколько причин, почему это предпочтительнее.

Фильтры по умолчанию Есть много ситуаций в реальных приложениях, где вам нужен фильтр по умолчанию. Например, снятая с производства продукция не продается. Если вы выставите продукты ObjectSet / DbSet напрямую, возникнут проблемы, если кто-то забудет применить фильтр по умолчанию. Это также позволяет избежать дублирования логики. Вы также можете изменить фильтр по умолчанию позже, не нарушая проблем.

public IQueriable<Product> GetAll()
{
    return context.Products.Where(p => !p.IsDiscontinued);
}

Soft Deletes Многие приложения используют мягкое удаление, когда вы сохраняете столбец, такой как IsDeleted, фактически не удаляя строку. Теперь ObjectSet / DbSet имеет метод Delete, но как только вы вызовете этот метод, он назначит значения null для обнуляемых свойств FK. Вы можете не хотеть этого.

public void Delete(Product product)
{
    // can apply any other logic here
    product.IsDeleted = true;
}

Только для чтения сущностей Существует много ситуаций, когда какое-то другое приложение отвечает за создание, удаление и обновление сущностей, а ваше приложение отображает только сущность. Но ObjectSet / DbSet предоставляет неподдерживаемую функциональность в этом случае. Еще одним преимуществом в этом случае будет использование опции NoTracking для сокращения времени материализации сущности.

Переключение доступа к данным без раскрытия реализации В некоторых случаях LINQ недостаточно. Здесь вы можете использовать сырой SQL или SP. Наличие репозитория позволит избежать использования различных методов запроса / обновления, когда функциональность, предоставляемая EF, недостаточна.

Работа с существующими базами данных Когда у вас нет возможности создать базу данных, которую EF может обработать. Существующая таблица может иметь столбцы Sql Variant, XML. Дублирование записей в другие таблицы и бесчисленное множество других случаев, которые вам нужно обработать, чтобы сохранить целостность базы данных.

Эти методы могут не быть пуленепробиваемыми, но пригодятся, если того потребует ситуация. Я бы посоветовал не переходить прямо к репозиториям, о которых вам лучше подумать, добавляет ли еще один уровень абстракции, необходимый для реализации необходимых функций.

2 голосов
/ 23 января 2012

шаблоны репозитория важны для отделения вашего механизма хранения данных от вашего приложения.Делая это, вы значительно облегчаете юнит-тестирование или замену структуры данных на более поздний срок.Прочитайте мой блог о том, как / почему я делаю это здесь: http://blog.staticvoid.co.nz/2011/10/staticvoid-repository-pattern-nuget.html

Лично я никогда больше не использую хранимые процедуры, поскольку в большинстве случаев я не вижу в них необходимости, однако реализовывать это с помощью своихШаблон репозитория Я бы порекомендовал вам создать новый RepositoryDataSource для сопоставления с вашей хранимой процедурой, а затем вызвать хранимую процедуру через EF или SQL старой школы.Я бы порекомендовал выдать какое-то исключение при обновлении или сохранении.

== РЕДАКТИРОВАТЬ (В ответ на вопрос «почему 2 слоя») ==

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

Например, вы можете поменять источник данных EF на версию в памяти.Это не обязательно должно изменить способ представления данных в приложении.

С другой стороны, вы можете кэшировать свои данные или предварительно регистрировать некоторую информацию о производительности операций записи в хранилище данных.Почему это должно иметь значение, какой реальный механизм хранения используется под крышками?

Лично я нашел разделение в этом конкретном месте, чтобы сделать решение гораздо более гибким.

...