Nhibernate дата сравнения - PullRequest
2 голосов
/ 01 декабря 2009

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

Когда я передаю orderPickDate в метод ниже, он никогда не возвращается с результатом. Я не хочу передавать диапазон дат, я просто хочу пропустить одну дату, игнорировать время, и если существуют какие-либо itemOrders с этой датой выбора, вернуть их.

public IList<ItemOrder> GetItemOrderByCriteria(int? itemNumber, int? warehouseNumber, DateTime? orderPickDate)
    {
        try
        {
            NHibernate.ICriteria criteria = NHibernateSession.CreateCriteria(typeof(Core.ItemOrder));

            if (itemNumber.HasValue)
                criteria.CreateCriteria("Item", "Item").Add(Expression.Eq("Item.ItemNumber", itemNumber.Value));


            if (warehouseNumber.HasValue)
                criteria.CreateCriteria("Warehouse", "Warehouse").Add(Expression.Eq("Warehouse.WarehouseNumber", warehouseNumber));

            if (orderPickDate.HasValue)
                criteria.Add(Expression.Eq("OrdPickDate", orderPickDate));

            return criteria.List<Core.ItemOrder>();
        }
        catch (NHibernate.HibernateException he)
        {
            DataAccessException dae = new DataAccessException("NHibernate Exception", he);
            throw dae;
        }

    }

Вот как этот столбец настроен в отображении:

<property name="OrdPickDate" column="ORD_PICK_DATE" type="date" not-null="true"/>

Когда я смотрю на создание sql nhibernate, он добавляет следующее предложение where (я передал его 01.12.2009, 12:00:00 AM):

WHERE  this_.ORD_PICK_DATE = '2009-12-01T00:00:00.00'

Если я пытаюсь выполнить запрос в редакторе БД, я получаю сообщение об ошибке «ORA-01861: литерал не соответствует строке формата». Должен ли я использовать другой подход при создании моих критериев?

1 Ответ

2 голосов
/ 01 декабря 2009

проблема, которую вы описываете, проистекает из того факта, что в Oracle тип DATE является моментом времени. Он всегда имеет компонент времени, даже если иногда он не отображается (компонент времени скрыт).

Чтобы выполнить поиск по дате, вам нужно:

  1. сравнить с диапазоном дат (WHERE dt BETWEEN :d1 AND :d2 или WHERE dt >= :d1 AND dt <= :d2)
  2. сравнить часть дня с датой (например, WHERE trunc(dt) = :d1)
  3. хранит только часть даты в вашем столбце (то есть для всех строк trunc(dt)=dt или, другими словами, все строки в "12:00 AM"), предпочтительно с применением ограничения столбца. WHERE dt = :d1 в этом случае будет работать.

Во всех случаях дерева вы должны поместить тип даты по обе стороны от операнда. Я предполагаю, что Hibernate естественно использует правильный тип данных, когда вы указываете «DATE». В SQL * Plus вы бы явно использовали правильный тип данных с функцией to_date:

WHERE  this_.ORD_PICK_DATE = to_date('2009-12-01 00:00:00', 
                                     'yyyy-mm-dd hh24:mm:ss')

Для решения проблем производительности: case (1) и (3) смогут использовать обычные индексы для столбца, а case (2) - нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...