这是我正在努力解决的问题。我想传递一个日期,然后使用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子句(我在12/1/2009 12:00:00 AM传递了它):
WHERE this_.ORD_PICK_DATE = '2009-12-01T00:00:00.00'
如果我尝试在db编辑器中运行查询,则会收到错误消息“ORA-01861:literal与格式字符串不匹配”。我应该采用不同的方法来创建我的标准吗?
答案 0 :(得分:2)
您所描述的问题来自于Oracle中DATE类型是一个时间点。它总是有时间组件,即使有时它没有显示(时间组件被隐藏)。
要执行日期搜索,您可以:
WHERE dt BETWEEN :d1 AND :d2
或 WHERE dt >= :d1 AND dt <= :d2
进行比较)WHERE trunc(dt) = :d1
)trunc(dt)=dt
,换句话说,所有行都位于“12:00 AM”),最好由列约束强制执行。在这种情况下,WHERE dt = :d1
会起作用。在所有树案例中,您都会在操作数的两侧放置日期类型。我想当你指定“DATE”时,Hibernate自然会使用正确的数据类型。在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)则不会。