NHibernate LIKE查询日期列

时间:2012-11-04 17:04:48

标签: c# sql datetime nhibernate sql-like

我正在使用以下代码动态过滤数据(我使用MySQL作为数据库引擎):

var filter = string.Empty;
if (!string.IsNullOrWhiteSpace(filterNumber))
{
    filter = "t.Number LIKE :filterNumber";
}
var query = string.Format("SELECT t FROM Table t WHERE 1=1 AND {0} ORDER BY {1} {2}", filter, orderBy, orderDirection);
var q = Session.CreateQuery(query);
if (!string.IsNullOrWhiteSpace(filterNumber))
{
    q.SetParameter<string>("filterNumber", "%" + filterNumber + "%");
}
q.SetFirstResult(offset);
q.SetMaxResults(limit);
return q.List<Table>();

(假设filterNumberorderByorderDirectionoffsetlimit是方法的参数,1=1仅为了这个目的而添加这个问题所以查询总是有效)

当Number是一个字符串(MySQL中的VARCHAR)列时它确实有效,但是当它是日期时间或整数列时它不起作用。

对于datetime,它会引发异常: could not execute query […] Name:filterDate - Value:%2012%和内部异常为Specified cast is not valid

对于整数/浮点列,例外是: could not execute query […] Name:filterPrice - Value:%100%和内部异常为Input string was not in a correct format

DatePrice是表格中的另一列)

如何在日期/数字列上动态创建这样的LIKE查询?这种查询在MySQL中运行良好:

SELECT * FROM `Table` WHERE `Date` LIKE '%2012%'

2 个答案:

答案 0 :(得分:2)

根据@usr评论,我设法在HQL中进行投射:

filter = "CAST(t.Date AS String) LIKE :filterDate";

它适用于日期和数字。

答案 1 :(得分:0)

如果可以避免使用LIKE和日期/数字,那可能不是一个好主意。如果打算在年份匹配,则应使用年份(alias.property)HQL函数(无需将查询转换为Criteria API,因为这是HQL语法)和常规equals运算符。或者更少/更多。

我怀疑SQL是通过自动转换为varchar工作的,但除非你确实需要模式匹配,否则我认为与使用日期提取或BETWEEN相比,它的性能要差得多。

如果确实需要模式匹配,则应将日期/数字转换为字符串。