用NHibernate对连续全名进行模糊搜索

时间:2011-07-15 15:29:03

标签: c# sql linq nhibernate fuzzy-search

我正在尝试将以下SQL转换为NHibernate:

SELECT * FROM dbo.Customer
WHERE FirstName + ' ' + LastName LIKE '%' + 'bob smith' + '%'

我试图做这样的事情,但它不起作用:

name = "%" + name + "%";

var customers = _session.QueryOver<Customer>()
            .Where(NHibernate.Criterion.Restrictions.On<Customer>(c => c.FirstName + ' ' + c.LastName).IsLike(name))
            .List();

我基本上要做的是能够在文本框中搜索客户名称,其示例值为“bob smith”,并使用上面SQL中的LIKE表达式搜索数据库。 / p>

如果我要错误地搜索FirstName和LastName列,请使用其他方法帮助我,但上面的SQL查询可以获得我需要的内容。

使用2种解决方案进行更新:

所以我现在找到了解决这个问题的两种方法。一种是使用Criteria API。以下帖子的答案非常有用:https://stackoverflow.com/a/2937100/670028

我找到了另一个解决方案,感谢我的一位有用的同事建议使用LINQ投影和匿名类型。这是使用LINQ的解决方案:

var customers = session.Query<Customer>()
    .Select( x => new { FullName = x.FirstName + " " + x.LastName, Customer = x } )
    .Where( x => x.FullName.Contains( "Bob Smith" ) )
    .Select( x => x.Customer )
    .ToList();

4 个答案:

答案 0 :(得分:10)

NHibernate无法将表达式转换为sql语句,因为它不知道如何处理c =&gt; c.FirstName +''+ c.LastName。解决方案可以将其重写为以下内容:

Session.CreateCriteria<Customer>()
    .Add(Restrictions.Like(
    Projections.SqlFunction("concat",
                            NHibernateUtil.String,
                            Projections.Property("FirstName"),
                            Projections.Constant(" "),
                            Projections.Property("LastName")),
    "Bob Whiley",
    MatchMode.Anywhere))

答案 1 :(得分:1)

如果您希望将代码保持为尽可能强类型,我就是这样做的。我需要在Disjunction中使用它。希望这有助于某人!

var disjunction = new Disjunction();
var fullNameProjection = Projections.SqlFunction(
    "concat",
    NHibernateUtil.String,
    Projections.Property<UserProfile>(x => x.FirstName),
    Projections.Constant(" "),
    Projections.Property<UserProfile>(x => x.LastName)
    );
var fullNameRestriction = Restrictions.Like(fullNameProjection, searchText, MatchMode.Anywhere);
disjunction.Add(fullNameRestriction);

答案 2 :(得分:0)

我认为它会是这样的:

.On(c =&gt; c.IsLike(c.FirstName +''+ c.LastName))

因为您没有按照现在的方式比较正确的值。

答案 3 :(得分:0)

我可以试试这个:

query.Where(Restrictions.On<MyType>(x => x.Field).IsLike(StringToSearch))

如果它与QueryOver或Criteria API过于复杂,您可以使用HQL语法