NHibernate查询的复杂标准:Linq或ICriteria?

时间:2010-12-07 18:00:50

标签: linq nhibernate linq-to-nhibernate sql-like

我在基本的存储库模型中使用NH2.1和FluentNH配置以及Linq2NH。我正在尝试设置一个查询,从winform中消化各种表单字段。标准几乎是一系列文本框,每个文本框都有一个复选框,说明条件是否包含通配符(仅支持星号),因此逻辑是一系列的:

...
&& Field1.IsNullOrBlank() || Field1 == Criteria1 || (Criteria1IsWildCard && Regex.Match(Field1, Criteria1.Replace("*",".*")))
&& Field2.IsNullOrBlank() || Field2 == Criteria2 || (Criteria2IsWildCard && Regex.Match(Field2, Criteria2.Replace("*",".*")))

现在,这对于Linq2Object来说非常棒,但是由于多种原因(自定义扩展方法,正则表达式检查等),它在Linq2NH查询中不会走得太远。

我创建了一个不同的搜索页面,它必须消化类似的数据,但是该查询是针对不同的Repository数据源执行的,该数据源需要将查询作为字符串(SalesForce SOQL)。由于NHibernate有许多更复杂的编译器检查工具,我更喜欢HQL是我的最后选择。

其他相关信息:

  • 检索和缓存整个表的内容以便使用Linq2Objects过滤结果几乎不可行(该表大约是15k记录),但是任何不必执行此操作的选项都是首选。
  • 用户需要拥有尽可能多的通配符;因此,使用StartsWith()/ EndsWith()/ Contains()解决方法是不可行的。

所以,问题是,你如何设置它来对抗NHibernate?

2 个答案:

答案 0 :(得分:0)

HQLICriteriaLinq-to-NH以及任何其他API最终都会转换为SQL。因此,由于MS-SQL Server和其他人不直接支持通配符,因此不能在标准中使用通配符。

答案 1 :(得分:0)

我得到的答案是使用StartsWith / EndsWith方法获取LIKE操作,然后用%替换任何星号。如果标准以星号开头,请使用EndsWith,否则使用StartsWith。这会将“abc *”转换为“abc %%”,将“* abc”转换为“%% abc”,将“* abc *”转换为“%% abc%”,这些都与非重复的%%通配符相同在LIKE条款中。它不能按规定工作的唯一情况是输入既不以通配符开头也不以通配符结束的标准;如果将“a * c”与abc,adc和abcde进行比较,它将评估为“a%c%”而不是“a%c”,并将返回所有这些而不是排除abcde。足够接近我的目的。