使用 NHibernate 对串联全名进行模糊搜索

发布于 2024-11-24 07:59:06 字数 1114 浏览 2 评论 0原文

我正在尝试将以下 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();

I am trying to convert the following SQL into NHibernate:

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

I was trying to do something like this but it is not working:

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

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

What I'm basically trying to do is be able to search for a customer's name in a text box with the example value of "bob smith" and for it to search the database using the LIKE expression in the SQL above.

If I'm going about searching the FirstName and LastName columns wrongly, please help me out with an alternative but the above SQL query gets me what I need.

Update with 2 solutions:

So I've now found two solutions to this problem. One is to use the Criteria API. The following post has an answer that works great: https://stackoverflow.com/a/2937100/670028

The other solution I found thanks to one of my helpful coworkers who suggested using a LINQ projection and anonymous types. Here's a solution using 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();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

渔村楼浪 2024-12-01 07:59:06

NHibernate 无法将表达式转换为 sql 语句,因为它不知道如何处理 c =>; c.名字 + ' ' + c.姓氏。解决方案可以将其重写为如下所示:

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

NHibernate is not able to translate the expression into a sql statement because is does not know what to do with c => c.FirstName + ' ' + c.LastName. A solution can be rewriting this to something like this:

Session.CreateCriteria<Customer>()
    .Add(Restrictions.Like(
    Projections.SqlFunction("concat",
                            NHibernateUtil.String,
                            Projections.Property("FirstName"),
                            Projections.Constant(" "),
                            Projections.Property("LastName")),
    "Bob Whiley",
    MatchMode.Anywhere))
烧了回忆取暖 2024-12-01 07:59:06

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

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

If you would like to keep your code as strongly-typed as possible, here is how I achieved it. I needed to use it in a Disjunction. Hope this helps someone!

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);
尤怨 2024-12-01 07:59:06

我认为它会是这样的:

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

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

I would think it would something like this:

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

Because you aren't comparing the right values the way you have it right now.

橘亓 2024-12-01 07:59:06

我可以尝试这个:

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

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

I can try this :

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

If it's too complexe with QueryOver or Criteria API you can use HQL syntax

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文