2013-06-19 14 views
17

Mam projekt z LINQ i chcę użyć w nim mojej własnej metody. Ta metoda NoWhiteSpaces powinna zwracać łańcuch górny bez spacji.Używanie mojej własnej metody z LINQ do Entry

public static class LittleExtensions 
{ 
    public static string NoWhiteSpaces(this String s) 
    { 
     return Regex.Replace(s, @"\s", string.Empty).ToUpper(); 
    } 
} 

Kiedy chcesz użyć tej metody z LINQ, tak:

static void GetHaendler() 
    { 
     using (var riaService = new gkmRia()) 
     { 
      var hladany = "someone"; 
      var haendlers = from hndlr in riaService.GetGkmHaendlerOutlet() 
          where hndlr.NameOutlet.NoWhiteSpaces() == hladany.NoWhiteSpaces() 
          select hndlr; 
      Console.Write(haendlers.First().NameOutlet); 
     } 
    } 

otrzymuję komunikat o błędzie:

LINQ do podmiotów nie rozpoznaje „system metody. String NoWhiteSpaces (System.String) "metoda, a tej metody nie można przetłumaczyć na wyrażenie magazynu.

Jakieś rozwiązanie? Dziękuję za Twój czas.

+0

Gdzie jest BezBielychZnakov()? –

+1

Czy dodałeś klauzulę "using" do swojej przestrzeni nazw w pliku, w którym wykonujesz wywołanie linq? – Serge

+1

Unikaj używania wyrażeń regularnych: 'return new string (s.Where (c =>! Char.IsWhitespace (c))).ToUpper() ' –

Odpowiedz

15

Niemożliwe jest użycie niestandardowych metod lub właściwości z LINQ do Entities, ponieważ LINQ to Entities musi być w stanie przetłumaczyć wyrażenie na instrukcję SQL, której nie może wykonać za pomocą tej metody.

Droga jest poruszać się ominąć LINQ do podmiotów i zamiast używać LINQ to Objects za pomocą Enumerable zamiast Queryable (uwaga AsEnumerable() w poniższym kodzie):

static void GetHaendler() 
{ 
    using (var riaService = new gkmRia()) 
    { 
     var hladany = "someone"; 
     var haendlers = from hndlr in riaService.GetGkmHaendlerOutlet().AsEnumerable() 
         where hndlr.NameOutlet.NoWhiteSpaces() == hladany.NoWhiteSpaces() 
         select hndlr; 
     Console.Write(haendlers.First().NameOutlet); 
    } 
} 

pamiętać, że ta powoduje zapytanie wykonać w aplikacji, a nie w bazie danych, więc może to mieć wpływ na wydajność. Jeśli to możliwe, lepiej zmienić zapytanie, aby można je było wyrazić przy użyciu methods supported by the Entity Framework.

Alternatywą wyrażenie, które jest obsługiwane przez LINQ do podmiotów może wyglądać następująco:

var hladany = "someone".NoWhiteSpaces(); 
var haenflers = from hndlr in riaService.GetGkmHaendlerOutlet(). 
       where hndlr.NameOutlet.Replace(" ", "").Replace("\t", "") == hladany 
       select hndlr; 

Przykład ten obsługuje tylko spacje i zakładek (regex obsługuje różne białe znaki, jak również), ale nie wiem Twoje dokładne wymagania, które mogą być wystarczające. Zawsze możesz połączyć więcej wywołań Replace, aby wykonać dodatkowe zamienniki.

+0

Dziękuję bardzo :-) Spróbuję! –

+4

@ a.farkas2508 Pamiętaj, że spowoduje to usunięcie wszystkich wyników, a następnie manipulację na kliencie. Jeśli używasz tego dla filtra, będzie to nieoptymalne. – Aron

+0

Dlatego podałem alternatywę, którą można przetłumaczyć na SQL. Zauważ, że nadal nie jest to optymalne, ponieważ każde zapytanie używające 'Zamień' nie może używać indeksu. – Sven

6

LINQ to Entities próbuje przetłumaczyć każdą wywołaną metodę na część kwerendy bazy danych, która jest wykonywana. Próbując przetłumaczyć twoją metodę, nie powiedzie się, ponieważ nie wie, jak ją reprezentować w SQL.

można obejść przez którąkolwiek

  • Wykonywanie zapytania i filtrować je po materializacji wyników (zły pomysł, chociaż jeśli obsługi dużych zbiorów danych) lub
  • Stosować wyłącznie obsługiwane metody (lepsze podejście IMO). można znaleźć listę obsługiwanych metod tutaj:
    CLR Method to Canonical Function Mapping
    jak metody String.Replace() i String.ToUpper() są obsługiwane, to powinno być łatwe, aby zastąpić metodę niestandardową z nim.
Powiązane problemy