NHibernate.Linq LIKE

23

如何使用NHibernate.Linq生成此查询?

WHERE this_.Name LIKE @p0; @p0 = 'test'  // Notice NO % wild card

注意,这不是 Linq To Sql 或 Entity Framework。这是 NHibernate。

编辑:

以下是使用 ICriteria 实现的期望查询:

criteria.Add(Expression.Like("Name", "test"));
return criteria.List<Theater>();
4个回答

28

虽然这个问题已经被标记为已解决,在那个时候是正确的,但我也想指出NHibernate现在有一些扩展,所以你可以这样做:

Session.QueryOver<MyEntity>()
    .Where(x => x.Property.IsLike("something", MatchMode.Anywhere))
    .List();

这将为您执行LIKE '%something%'


1
顺便说一下,这些都是开箱即用的,而不是定制构建的。 - Kieran Senior
+1 正是我在寻找的,值得注意的是,为了解决上述确切问题,您需要使用MatchMode.Exact(无%通配符)。 - PJUK
2
在不使用Resharper的情况下,需要添加using NHibernate.Criterion;。但是效果很好!谢谢。 - Russell B
3
问题是关于Linq to NHibernate,而不是Query over。 - Phil

18

我相信这就是你要找的内容:

var theaters = from theater in Session.Linq<Theater>() 
               where theater.Name.Contains("test") 
               select theater;
根据我的测试,它生成了一个SQL的'LIKE'语句: "... WHERE theater.Name LIKE %test%",这正是你提供的条件片段的输出。

1
使用题目中提供的条件,我没有看到生成百分号通配符。 - mxmissile
我刚刚运行了单元测试,使用我在答案中提供的代码,并生成了一个带有%通配符的SQL语句,用于搜索字符串的两端。 我还使用相同的测试运行了Criteria等效项,如果我使用criteria.Add(Expression.Like("Name", "test", MatchMode.Anywhere));,则会得到完全相同的SQL语句。我使用NHibernate 2.1和SQL Server 2005。 如果您使用相同的配置,则应该能够看到相同的结果。 - tolism7
问题在于我不想在Linq中使用通配符。我上面的评论是在回应你的答案“正是你提供的条件片段的输出”。如果我没有表达清楚,对不起。我可以使用问题中所述的ICriteria实现所需的查询,但似乎无法使用Linq实现。 - mxmissile
2
所以你想生成一个没有包含%通配符的LIKE语句来搜索字符串。正如你所说,你已经在Criteria中这样做了,但你希望用LINQ实现相同的功能。我很抱歉误读了你最初的评论...我可以问一下为什么有人会想要这样做吗?我认为没有通配符的LIKE操作符与使用'='操作符相同或者至少被优化成相同的操作。 - tolism7
1
是的,那就是我的问题。之所以这样是因为给定的条件LIKE 'test'会返回带有'TEST'而不是'TESTEST'的值。换句话说,'Test' != 'test'。所以基本上只是为了忽略大小写。希望这样说得清楚明白。 - mxmissile

18
我在我的项目中也遇到了同样的问题,找到了解决方案:
session.Linq<Theater>()
    .Where(x => x.Name.StartsWith("test") && x.Name.EndsWith("test");

这句话的 SQL 翻译为:
SELECT ... WHERE Name LIKE '%test' AND Name LIKE 'test%'

4
补充说明:&& x.Name.Length == "test".Length。否则,你将得到诸如test blah blah blah test的结果。 - J. Ed
6
我可能没有理解错,但是你实际上并不是在进行“类似”的操作,而是在进行“相等”的操作……其中 x => x.Name.Equals("test") 的意思是筛选名字为“test”的对象。 - Mark Powell
确实如 @n3rd 所说。 - Johnny_D
如果搜索文本位于中间,则此方法将无效。例如,如果您键入“cks”,则单词“Jackson”将不会出现。 - Phil
2
我知道。这个问题涉及到没有通配符的LIKE语句。请查看他在第一行的评论。 - CMerat

8

在NH4(可能稍早),内置了NHibernate.Linq命名空间中的Like字符串扩展:Like(this string matchExpression, string sqlLikePattern)。(它定义在NHibernate.Linq.SqlMethods扩展类上。)

using NHibernate.Linq;
...
session.Query<Theater>()
    .Where(t => t.Name.Like("test"));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接