2011-07-15 10 views
5

Próbuję przekonwertować następujący kod SQL w NHibernate:Fuzzy Szukaj w łączonych Pełna nazwa użyciu NHibernate

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

Starałem się zrobić coś takiego, ale to nie działa:

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

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

Co zasadniczo próbuję zrobić, to móc wyszukać nazwisko klienta w polu tekstowym z przykładową wartością "bob smith" i przeszukać bazę danych za pomocą wyrażenia LIKE w powyższym SQL.

Jeśli chodzi o wyszukiwanie kolumn FirstName i LastName błędnie, proszę, pomóżcie mi z alternatywą, ale powyższe zapytanie SQL zapewnia mi to, czego potrzebuję.

Aktualizacja z 2 rozwiązań:

Tak już teraz znaleźć dwa rozwiązania tego problemu. Jednym z nich jest użycie API Criteria. Poniższy post ma odpowiedź, która działa świetnie: https://stackoverflow.com/a/2937100/670028

Inne rozwiązanie znalazłem dzięki jednemu z moich pomocnych współpracowników, którzy zasugerowali użycie projekcji LINQ i typów anonimowych. Oto rozwiązanie przy użyciu 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(); 
+0

Będziesz musiał użyć 'Ograniczenia.Lika' na Projekcji przy użyciu funkcji concat. Nie sądzę, że NH jest wystarczająco inteligentny, aby zbudować dla ciebie projekcję concat. – dotjoe

+0

Aktualizacja: Zauważyłem, że kod NHibernate jest po prostu zbyt brudny w tym przypadku i poszedł po procedurze przechowywanej. Naprawdę staram się unikać procedur przechowywanych tak często, jak to możliwe, ale czasami łatwiej jest uruchomić obsługę sql. –

Odpowiedz

10

NHibernate nie jest w stanie przetłumaczyć wyraz w sql bo znaczy nie robi wiedzieć, co zrobić z c => c.FirstName + '' + c.LastName. Rozwiązanie to może być przepisanie do czegoś takiego:

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

Powróciłem do tego wpisu i wypróbowałem ten kod i chociaż nie działało to poprawnie, udało mi się znaleźć właściwe rozwiązania, by znaleźć inne rozwiązania. Poniższe rozwiązanie z innej odpowiedzi StackOverflow działało idealnie, po prostu pomyślałem, że będę się dzielić: http://stackoverflow.com/a/2937100/670028 –

+0

cześć randy, jeśli masz go w pracy, możesz edytować post, aby poprawić odpowiedź, a następnie oznacz to jako właściwą odpowiedź, aby podzielić się nią ze światem. – Peter

0

to myślę, że będzie coś takiego:

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

Ponieważ nie porównujesz właściwych wartości w taki sposób, jak teraz.

0

mogę spróbować to:

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

Jeśli jest zbyt Complexe z QueryOver lub Criteria API można użyć składni HQL

1

Jeżeli chcesz zachować swój kod tak silnie wpisany, jak to możliwe, oto jak się go osiągnąć. Musiałem go użyć w Disjunction. Mam nadzieję, że to pomoże komuś!

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); 
Powiązane problemy