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();
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))
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With