0

我正在使用以下代码来动态过滤数据(我使用 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,orderDirectionoffsetlimit方法的参数并且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%'
4

2 回答 2

2

根据@usr 评论,我设法在 HQL 中进行了强制转换:

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

它适用于日期和数字。

于 2012-11-04T20:14:25.667 回答
0

如果可以避免的话,将 LIKE 与日期/数字一起使用可能不是一个好主意。如果打算在年份匹配,则应使用 year(alias.property) HQL 函数(无需将查询转换为 Criteria API,因为这是 HQL 语法)和常规等号运算符。或小于/大于。

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

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

于 2012-11-04T18:04:57.700 回答