nhibernate queryover LIKE 与表达式树
我希望向我的基本存储库类添加一个方法,该方法允许我使用 LIKE 表达式,但我不太确定如何进行此操作。我想创建一个通用方法,该方法查看传入的表达式树并在传入的字符串值中查找通配符。然后它将相应地生成 QueryOver 语句。
我目前有以下内容:
public IList<T> FindAll(Expression<Func<T, bool>> criteria, char wildCard)
{
return SessionFactory.GetCurrentSession()
.QueryOver<T>()
.Where(criteria)
.List();
}
显然困难的部分还没有到来。我需要查看表达式树并使用 QueryOver
动态构建查询。寻找有关如何继续此操作的一些指示。或者我只是在这里浪费时间,应该在我的存储库中创建处理 LIKE 查询的单独方法?
理想情况
下,我想告诉以下内容之间的区别:
- search*
- *search
- *search*
因此生成的查询将是:
- field LIKE 'search%'
- field LIKE '%search'
- field LIKE '%search%'
I'm looking to add a method to my base repository class that allows me to use LIKE expressions but I'm not quite sure of how to go about this. I want to create a generic method that looks at the expression tree passed in and looks for wildcard characters in the string values passed in. It would then generate the QueryOver
statement accordingly.
I have the following currently:
public IList<T> FindAll(Expression<Func<T, bool>> criteria, char wildCard)
{
return SessionFactory.GetCurrentSession()
.QueryOver<T>()
.Where(criteria)
.List();
}
Obviously the hard part is yet to come. I need to look through the expression tree and build the query using QueryOver
dynamically. Looking for some pointers on how to proceed with this. Or am I just wasting my time here and should just create individual methods in my repositories that handle the LIKE queries?
Additional Criteria
Ideally I'd like to tell the difference between the following:
- search*
- *search
- *search*
So the query generated would be:
- field LIKE 'search%'
- field LIKE '%search'
- field LIKE '%search%'
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在 QueryOver 中编写 Like 表达式有两种方法。
如果您在Where 子句之外执行此操作:
但是写起来有点长。
所以你可以使用WhereRestrictionOn:
这意味着你需要传入两个参数,例如:
你也许可以使用.Contains,.StartsWith,.EndsWith,但我不确定。
我认为这些在 NHibernate 中不起作用。
希望有帮助。
There's two ways to write a Like expression in QueryOver.
If you do it off the Where clause:
However this is kinda long to write.
So you can use WhereRestrictionOn:
This means you need to pass in two parameters like:
You may be able to use .Contains, .StartsWith, .EndsWith, but I'm not sure.
I don't think those work in NHibernate.
Hope that helps.
我真的不明白你想做什么。您是否想要一个查询,例如
生成一个property LIKE“%substring%”查询?在大多数 Linq 提供程序中,String.Contains 方法在“LIKE”查询中进行转换,因此您不需要在表达式树中查找通配符,只需在 String.Contains 方法中查找。
对于后者,您必须解析表达式树以查找 String.Contains() 方法。这可能会很麻烦(http://msdn.microsoft.com/en-us/library/bb397951.aspx)。另外,我在您的方法中看不到哪个属性要与 LIKE 运算符“比较”。
无论如何,我认为将 ICriterion 传递给您的 .Where() 会更容易,例如
,并在之后用 .And() 附加您的其他条件。缺点是丢失强类型查询。
I don't really understand what you want to do. Do you want for a query such as
to generate a property LIKE "%substring%" query? In most Linq providers the String.Contains method is transformed in a "LIKE" query, and thus you wouldn't need to look for wildcard characters in the expression tree, only for the String.Contains method.
In case of the latter, you would have to parse the expression tree looking for a String.Contains() method. This could be very troublesome (http://msdn.microsoft.com/en-us/library/bb397951.aspx). Also, I can't see in your method which property is to be "compared" with the LIKE operator.
Anyways, I think it would be easier to pass a ICriterion to your .Where(), such as
, and append your other conditions with .And() right after that. The drawback is losing strongly-typed queries.
在深入研究了将表单表达式转换
为表单 SQL
的问题的解决方案后,我想出了以下解决方案: Yu 必须为标准字符串函数 .Contains()、.StartsWith 注册自定义方法调用, .EndsWith()。
天知道为什么这些函数没有在 NHibernate 中默认注册。下面的代码应该可以帮助你。
After digging for a while for a solution about the problem of translating expressions of the form
into SQL of the form
I came up with the following solution: Yu have to Register custom method calls for the Standard string functions .Contains(), .StartsWith, .EndsWith().
God knows why these functions are not registered by default within NHibernate. The following code should help you out.