Замена NHibernate fluent (QueryOver) на HQL с коррелированным подзапросом

Фон, с использованием FluentNHibernate, последняя сборка разработчика, работающая с NHibernate 3.0.

Вот объявления типов для WorkIncident:

// Enumeration used in class below.
public enum TicketStatus
{
    Open = 1,
    Closed = 10,
    Hold = 20
}

// Ticket class.
public class WorkIncident
{
    public virtual int EntryId { get; set; }
    public virtual int TicketNumber { get; set; }
    public virtual string ModifierNtId { get; set; }
    public virtual DateTime ModifiedDate { get; set; }
    public virtual TicketStatus Status { get; set; }
    public virtual int Version { get; set; }
    public virtual string Title { get; set; }
    public virtual string Details { get; set; }
}

// FluentNHibernate mapping
public class WorkIncidentMap : ClassMap<WorkIncident>
{
    public WorkIncidentMap()
    {
        Table("incident_details");
        Id( wi => wi.EntryId, "wiid");
        Map(wi => wi.TicketNumber, "workitem_number");
        Map(wi => wi.Title, "workitem_title");
        Map(wi => wi.Details, "workitem_comment");
        Map(wi => wi.ModifiedDate, "workitem_modified_on");
        Map(wi => wi.ModifierNtId, "modified_by_worker_nt_id");
        Map(wi => wi.Status, "workitem_status_lookup_id").CustomType<EnumType<Status>>();
        Map(wi => wi.Version, "workitem_version");
    }
}

Сопоставление работает нормально, и я могу без проблем выполнять запросы, подобные приведенным ниже :

session.QueryOver<AltirisIncident>()
    .Where(ai => ai.ModifierNtId == worker.Name.Replace("\\", @"\"))
    .AndRestrictionOn(ai => ai.ModifiedDate)
    .IsBetween(DateTime.Today)
    .And(DateTime.Today.AddDays(1))
    .List<WorkIncident>();

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

Однако у меня возникли проблемы с переводом следующего HQL в беглое объявление:

from    WorkIncident as t1
where   t1.ModifierNtId = :ntid
and     t1.ModifiedDate between :startdate and :enddate
and     t1.Status = :status
and     (t1.Version = 1
or      t1.TicketNumber in (
    select    t2.TicketNumber
    from      WorkIncident as t2
    where     t2.Status != t1.Status
    and       t2.TicketNumber = t1.TicketNumber
    and       t2.Version = t1.Version - 1))

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

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

6
задан Joseph Alcorn 21 March 2011 в 21:45
поделиться