16

chcę szukać to:Linq to Entities (EF 4.1): Jak zrobić SQL LIKE z symbolem wieloznacznym w środku ("% term% term%")?

Post Cereal 

i uzyskać w ten sposób:

Post Honey Nut Cereal 

gdzie dzikie karty byłyby przestrzenie.

Wiem, że mógłbym zrobić SPLIT i serię AND i Contains() i tłumaczenie do wyrażenia Linq dla każdego terminu jako obiektu specyfikacji, ale czy nie istnieje sposób na uhonorowanie symboli wieloznacznych w terminie wysłanym do SQL ? Zajrzałem do funkcji SQL, gdzie jest w Linq do SQL, ale nie jestem pewien, co to jest w Linq do Entities.

chciałbym zrobić coś takiego:

term = '%' + term.Replace(' ', '%') + '%'; 
db.table.where(p => System.Data.Objects.SqlClient.SqlFunctions 
        .SqlMethods.Like(p.fieldname, term)); 

sugestie?

Odpowiedz

43

wierzę można użyć SqlFunctions.PatIndex:

dt.Table.Where(p => SqlFunctions.PatIndex(term, p.fieldname) > 0); 

SqlFunctions.PatIndex zachowuje się tak samo jak operator SQL LIKE. Obsługuje wszystkie standardowe symbole wieloznaczne tym:

  • % dowolny ciąg zero lub więcej znaków.
  • _ (podkreślenie) Dowolny pojedynczy znak.
  • [] Dowolny pojedynczy znak w podanym zakresie ([a-f]) lub zestaw ([abcdef]).
  • [^] Dowolny pojedynczy znak spoza określonego zakresu ([^ a-f]) lub zestawu ([^ abcdef]).

SqlFunctions.PatIndex często jest dostępna, gdy SqlMethods.Like nie jest dostępna (w tym w kontrolerach MVC)

+1

To zasługuje na więcej głosów. To działało idealnie dla mnie bez większej złożoności. –

+0

Dr Zim ma rację, szukał rozwiązania przez kilka godzin i jest to zdecydowanie najprostszy, jaki znalazłem. – user1841243

+0

Próbowałem tego w .NET i bezpośrednio w TSQL i żaden sposób nie pracował dla mnie. Korzystanie z EF 5, .NET 4.5 i VS 2012 – Matt

5

Prawdopodobnie jest łatwiej ominąć LINQ i użyć filtru Entity SQL:

var query - db.table.Where("TRIM(fieldname) LIKE @pattern"); 
query.Parameters.Add(new ObjectParameter("pattern", term)); // term == "%what%ever%" 

i rodzaj query narzędzi IQueryable<TEntity> więc można zastosować dodatkowe operatory LINQ.

+0

Próbuję tego w LINQPad, ale uzyskać ten wyjątek: 'EntitySqlException:" BusinessName "nie może być rozwiązany w bieżącym zakresie lub kontekście. Upewnij się, że wszystkie odnośne zmienne są w zasięgu, że wymagane schematy są załadowane i że przestrzenie nazw są poprawnie przywoływane. "Gdzie" BusinessName "jest kolumną, którą próbuję filtrować. Nie mogę wymyślić, jak przejść przez to. –

+0

@adrift Musisz ustawić LINQPad z informacjami kontekstowymi, ledwie go używam, więc nie mogę naprawdę pomóc (IIRC właśnie odwoływałem się do zestawu z kontekstem i typami encji). – Richard

+1

Używanie encji SQL jest tylko jednym ze sposobów, aby to zrobić - L2E nie obsługuje tego typu wyszukiwania wieloznacznego. Aby rozwiązać problem, spróbuj użyć 'it.BusinessName'. Kolumny w ESQL muszą być poprzedzone prefiksem, a "it" jest domyślnym prefiksem - [tutaj] (http://stackoverflow.com/questions/6202036/entity-framework-v4-1-like/6202346#6202346) jest pełnym przykładem zapytania . –

0

prostu do wyjaśnienia komentarz Ladislav w sprawie it.BusinessName. Myślę, że to, o czym mówi, to przedrostek nazwy pola z .it. Powyższe rozwiązanie działa tak długo, jak przedrostek nazwy pola w klauzuli where z it.. Również nie potrzebowałem TRIM() w moim przypadku.

var query - db.table.Where("it.fieldname LIKE @pattern"); 
query.Parameters.Add(new ObjectParameter("pattern", term)); // term == "%what%ever%" 

To działało doskonale w stosunku do bazy danych Oracle.

Powiązane problemy