Использование той же спецификации для кода и NHibernate QueryOver <T> - PullRequest
0 голосов
/ 21 июля 2011

Сценарий

Я работаю над приложением, в котором есть небольшой раздел, предназначенный для отображения статистики о текущем состоянии системы.Это включает в себя такие вещи, как, сколько элементов просрочено, количество всех ожидающих элементов, количество всех элементов без фильтров.Когда пользователь открывает приложение, он должен выбрать, над какими метками элементов он хочет работать, прежде чем видеть какие-либо элементы в интерфейсе пользователя.Как только это будет сделано, база данных будет запрошена и вернет список обратно пользователю.Каждый элемент имеет связанную метку.Метка элемента генерируется автоматически до того, как ее увидят пользователи.Одной из этих меток может быть «Просрочено», которая указывает пользователю, что она должна быть завершена первой.

Проблема

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

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

Моя модель представления, связанная с моим пользовательским интерфейсом, содержит следующее:

public bool IsOverdue
{
    get
    {
        return
            LabelName == "Please Advise" &&
            DateTimeProvider.Current.DateTime.AddDays(2) > WorkToBeginDateTime;
    }
}

public void TakeActionIfOverdue()
{
    if(IsOverdue)
    {
        LabelName = "Overdue";
        LabelBackground = "#123456";
    }
}

Я вызываюTakeActionIfOverdue() всякий раз, когда я строю свое дерево, которое при необходимости переопределяет имя метки.

И мой запрос NHibernate выглядит так:

Domain.Locate locateAlias = null;
Status statusAlias = null;

var overdueCountQuery = _session.QueryOver(() => locateAlias)
    .Select(Projections.RowCount())
    .JoinAlias(() => locateAlias.Status, () => statusAlias)
    .Where(() => statusAlias.Name == "Please Advise")
    .Where(() => locateAlias.WorkToBeginDateTime
        .IsBetween(DateTimeProvider.Current.DateTime.Subtract(new TimeSpan(48, 0, 0)))
        .And(DateTimeProvider.Current.DateTime))
    .Where(() => locateAlias.IsComplete == false)
    .FutureValue<int>();

Как видите, логика определяетэлемент просрочен в двух местах.

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

- Some Heading
    - Item #1 (Foo Label)
    - Item #3 (Bar Label)
- Another Heading
    - Item #2 (Bar Label)
    - Item #4 (Bar Label)
    - Item #6 (Overdue)

В этом сценарии пользователь выбрал метки Foo Label и Bar Label.Ради этого примера давайте представим, что Item #6 имеет метку Bar Label.Тем не менее, пользовательский интерфейс показывает, что у него есть метка Overdue, потому что он должен был быть выполнен 2 дня назад.

И мой маленький блок статистики выглядит следующим образом.

Items Overdue: 4
Pending Items: 45
All Items: 49

Вопрос

Как я могу централизовать эту логику?

1 Ответ

0 голосов
/ 01 января 2013

Используйте библиотеку QueryOver, чтобы создавать классы спецификаций без проблем с производительностью и с простыми функциями QueryOver.Единственная проблема - это зависимость с NHibernate, поскольку LINQ должен быть моделью по умолчанию для выполнения запросов.

        var list =
            repository.Find(courseWithVotes.By().And(courseByExample.By(new Course() { Name = "ava" })));

Примеры: http://queryoverspec.codeplex.com/

...