Внедрение шаблона спецификации платформы Entity Framework

Как реализовать шаблон спецификации с платформой Entity Framework?

Ответ 1

  • Спецификация:
    Для тех, кто хочет учебник, посетите ссылку .

  • Понять спецификацию для платформы Entity:
    Прочитайте this. Это касается следующих очень важных моментов. В любом приложении реального мира вы быстро захотите объединить несколько спецификаций вместе. Это называется составом спецификаций. Вам нужно будет понять некоторые из оговорок для разрешения спецификации композиции в Linq для Entities. Вы должны знать это, потому что использование Linq to Entities - это желательный подход к выражению критериев удовлетворенности спецификации.

  • Исправить ошибку:
    Загрузите и установите this. Он исправляет недостаток Linq для сущностей, о котором вы читали на втором шаге. Это объясняет более подробную информацию об исправлении.

  • Внедрить это!
    У вас должно быть достаточно информации для реализации шаблона. Держите googling. Выполнение этого для EF не совсем просто, но стоит того. Этот - очень интересная реализация.

Ответ 2

В принципе, при реализации шаблона спецификации не должно быть ничего специального (из-за EF). Вы реализуете спецификации как отдельные классы, которые работают с вашей моделью домена.

Вы можете найти много статьи или веб-трансляции о шаблоне спецификации и даже некоторых, которые используют EF, например здесь и здесь.

Ответ 3

Просто используйте NSpecification lib. Это бесплатно. Вы можете использовать его с любым ORM на основе интерфейса IQueryable, таким как Entity Framework или Linq2Sql: https://github.com/jnicolau/NSpecifications

Или получить его от Nuget:

Спецификации установки пакета -Version 1.1.0

Ответ 4

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

Обычно люди предоставляют другой метод в интерфейсе спецификации, представляющий дерево выражений, которое должно быть отправлено в Entity Framework:

public interface ISpecification<T>
{
    bool IsSpecifiedBy(T item);
    Expression<Func<T, bool>> GetPredicate()
}

Хранилище GetPredicate метод GetPredicate и передаст его методу Where в DbSet EF. Таким образом, вы ограничили, какие выражения будут генерироваться, и гарантируете, что он сгенерирует допустимый оператор SQL.

Чтобы включить логические операторы в спецификации, вам нужно смешать выражения вместе. есть этот пост от Владмира Хорикова, где он подробно объясняет, как это сделать.

Мне обычно не нравится это решение, поскольку оно предполагает, что ваша модель предметной области совпадает с моделью персистентности. Большинство людей в порядке с этим. Но мне нравится держать вещи ОЧЕНЬ разделенными на луковой архитектуре.

По своему опыту я обнаружил, что в конечном итоге Entity Framework будет загрязнять модель вашего домена с помощью dbcontexts, атрибутов EF, открытых сеттеров, свойств, которые имеют смысл только для базы данных, и т.д.

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

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

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

Я недавно написал серию постов, где я объясняю