我正在使用以下代码动态过滤数据(我使用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>();
(假设filterNumber
,orderBy
,orderDirection
,offset
和limit
是方法的参数,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
。
(Date
和Price
是表格中的另一列)
如何在日期/数字列上动态创建这样的LIKE查询?这种查询在MySQL中运行良好:
SELECT * FROM `Table` WHERE `Date` LIKE '%2012%'
答案 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相比,它的性能要差得多。
如果确实需要模式匹配,则应将日期/数字转换为字符串。