Migruję niektóre rzeczy z jednego serwera mysql na serwer sql, ale nie mogę dowiedzieć się, jak sprawić, by ten kod działał:
using (var context = new Context())
{
...
foreach (var item in collection)
{
IQueryable<entity> pages = from p in context.pages
where p.Serial == item.Key.ToString()
select p;
foreach (var page in pages)
{
DataManager.AddPageToDocument(page, item.Value);
}
}
Console.WriteLine("Done!");
Console.Read();
}
Kiedy wchodzi w sekundę foreach (var page in pages)
, rzuca wyjątek mówiąc:
LINQ to Entities nie rozpoznaje metody „System.String ToString ()” i tej metody nie można przetłumaczyć na wyrażenie magazynu.
Czy ktoś wie, dlaczego tak się dzieje?
Odpowiedzi:
Po prostu zapisz ciąg w zmiennej tymczasowej, a następnie użyj tego w swoim wyrażeniu:
Problem pojawia się, ponieważ
ToString()
nie jest tak naprawdę wykonywany, jest przekształcany w grupę MethodGroup, a następnie analizowany i tłumaczony na SQL. Ponieważ nie maToString()
odpowiednika, wyrażenie zawodzi.Uwaga:
Sprawdź również odpowiedź Alexa dotyczącą
SqlFunctions
klasy pomocnika, która została dodana później. W wielu przypadkach może to wyeliminować potrzebę stosowania zmiennej tymczasowej.źródło
ToString()
nie jest jedną z nich.ExecuteQuery
lub przy użyciu Entity SQL zObjectQuery<T>
Jak odpowiedzieli inni, to się psuje, ponieważ .ToString nie może przetłumaczyć na odpowiedni kod SQL w drodze do bazy danych.
Jednak firma Microsoft udostępnia klasę SqlFunctions, która jest zbiorem metod, których można używać w takich sytuacjach.
W tym przypadku szukasz tutaj SqlFunctions.StringConvert :
Dobrze, gdy rozwiązanie ze zmiennymi tymczasowymi nie jest pożądane z jakichkolwiek powodów.
Podobnie jak SqlFunctions, masz również EntityFunctions (z EF6 przestarzałą przez DbFunctions ), które zapewniają inny zestaw funkcji, które są również niezależne od źródła danych (nie są ograniczone do np. SQL).
źródło
Problem polega na tym, że wywołujesz ToString w zapytaniu LINQ to Entities. Oznacza to, że parser próbuje przekonwertować wywołanie ToString na jego równoważny SQL (co nie jest możliwe ... stąd wyjątek).
Wszystko, co musisz zrobić, to przenieść wywołanie ToString do osobnej linii:
źródło
Miałem podobny problem. Rozwiązano to, wywołując ToList () w kolekcji jednostek i wysyłając zapytanie do listy. Jeśli kolekcja jest mała, jest to opcja.
Mam nadzieję że to pomoże.
źródło
Zmień to w ten sposób i powinno działać:
Powodem, dla którego wyjątek nie jest zgłaszany w wierszu, w którym zostało zadeklarowane zapytanie LINQ, ale w wierszu
foreach
jest funkcja odroczonego wykonywania, tj. Zapytanie LINQ nie jest wykonywane, dopóki nie spróbujesz uzyskać dostępu do wyniku. Dzieje się to wforeach
i nie wcześniej.źródło
Rzutuj tabelę na
Enumerable
, a następnie wywołasz metody LINQ z użyciemToString()
metody wewnątrz:Ale bądź ostrożny, kiedy wywołujesz
AsEnumerable
lubToList
metody, ponieważ będziesz żądać wszystkich danych od wszystkich encji przed tą metodą. W moim przypadku powyżej czytam wszystkietable_name
wiersze jednym żądaniem.źródło
Uaktualnienie do Entity Framework w wersji 6.2.0 działało dla mnie.
Byłem wcześniej w wersji 6.0.0.
Mam nadzieję że to pomoże,
źródło
W MVC załóżmy, że szukasz rekordów na podstawie swoich wymagań lub informacji. Działa poprawnie.
źródło
Jeśli naprawdę chcesz wpisać
ToString
wewnątrz zapytania, możesz napisać odwiedzającego drzewo wyrażeń, który przepisuje wywołanie doToString
z wywołaniem odpowiedniejStringConvert
funkcji :źródło
First
tutaj jestGetMethods()
zwracanie wynikówMethodInfo[]
. AFAIK,MethodInfo[]
nie maFind
metody ani nie ma takiej metody rozszerzającej. Ale naprawdę powinienem użyć,Single
ponieważ ta metoda jest znajdowana przez odbicie i nie będzie błędu w czasie kompilacji, jeśli nie można rozwiązać odpowiedniej metody.W tym przypadku mam ten sam błąd:
Po spędzeniu zbyt dużej ilości czasu na debugowaniu zorientowałem się, że w wyrażeniu logicznym pojawił się błąd.
Pierwsza linia
search.Contains(log.Id.ToString())
działa dobrze, ale ostatnia linia, która zajmuje się obiektem DateTime, spowodowała żałosną awarię:Usuń problematyczną linię i problem rozwiązany.
Nie do końca rozumiem, dlaczego, ale wydaje się, że ToString () jest wyrażeniem LINQ dla ciągów, ale nie dla jednostek. LINQ for Entities obsługuje zapytania do bazy danych, takie jak SQL, a SQL nie ma pojęcia ToString (). W związku z tym nie możemy wrzucić ToString () do klauzuli .Where ().
Ale jak w takim razie działa pierwsza linia? Zamiast ToString (), SQL ma
CAST
iCONVERT
, więc jak dotąd moje najlepsze przypuszczenie jest takie, że linq dla encji używa tego w niektórych prostych przypadkach. Obiekty DateTime nie zawsze są tak proste ...źródło
Po prostu zamień zapytanie LINQ to Entity na zapytanie LINQ to Objects (np. Wywołanie ToArray) w dowolnym momencie, gdy musisz użyć wywołania metody w zapytaniu LINQ.
źródło