【问题标题】:Fuzzy Search on a Concatenated Full Name using NHibernate使用 NHibernate 对串联全名进行模糊搜索
【发布时间】:2011-10-06 06:31:09
【问题描述】:

我正在尝试将以下 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 表达式搜索数据库。

如果我错误地搜索 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();

【问题讨论】:

  • 您必须在使用 concat sqlfunction 的 Projection 上使用 Restrictions.Like。我认为 NH 不够聪明,无法为您构建字符串 concat 投影。
  • 更新:我发现 NHibernate 代码在这种情况下太乱了,只是简单地使用了一个存储过程。我真的尽量避免使用存储过程,但有时自己编写 sql 会更容易。

标签: c# sql linq nhibernate fuzzy-search


【解决方案1】:

NHibernate 无法将表达式转换为 sql 语句,因为它不知道如何处理 c => 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))

【讨论】:

  • 我重新访问了这篇文章并尝试了这段代码,虽然它不能正常工作,但它让我走上了寻找其他解决方案的正确轨道。来自另一个 StackOverflow 答案的以下解决方案效果很好,只是想我会分享:stackoverflow.com/a/2937100/670028
  • 嗨,兰迪,如果您成功了,您可以编辑帖子以更正答案,然后将其标记为正确答案以与全世界分享。
【解决方案2】:

如果您想让您的代码尽可能地强类型化,这就是我实现它的方法。我需要在析取中使用它。希望这对某人有帮助!

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);

【讨论】:

    【解决方案3】:

    我想应该是这样的:

    .On(c => c.IsLike(c.FirstName + ' ' + c.LastName))

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

    【讨论】:

      【解决方案4】:

      我可以试试这个:

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

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

      【讨论】:

        猜你喜欢
        • 2020-05-06
        • 2016-11-20
        • 1970-01-01
        • 2016-01-18
        • 2021-06-11
        • 1970-01-01
        • 1970-01-01
        • 2011-10-06
        • 1970-01-01
        相关资源
        最近更新 更多