Podczas korzystania z EntityFrameworkA lambda expression with a statement body cannot be converted to an expression tree
pojawia się błąd „ ” podczas próby skompilowania następującego kodu:
Obj[] myArray = objects.Select(o =>
{
var someLocalVar = o.someVar;
return new Obj() {
Var1 = someLocalVar,
Var2 = o.var2 };
}).ToArray();
Nie wiem, co oznacza błąd, a przede wszystkim jak go naprawić. Jakaś pomoc?
c#
linq
entity-framework
linq-to-entities
pistacchio
źródło
źródło
Odpowiedzi:
Czy
objects
kontekst bazy danych Linq-To-SQL? W takim przypadku możesz używać prostych wyrażeń po prawej stronie operatora =>. Powodem jest to, że te wyrażenia nie są wykonywane, ale są konwertowane na SQL, aby były wykonywane na bazie danych. Spróbuj tegoźródło
W wyrażeniach lamba można używać treści instrukcji dla kolekcji IEnumerable . Spróbuj tego:
Uwaga:
Korzystając z tej metody, zastanów się ostrożnie, ponieważ w ten sposób wszystkie zapytania zostaną zapisane w pamięci, co może mieć niepożądane skutki uboczne w pozostałej części kodu.
źródło
AsEnumerable()
maski, mój problem zniknął!Oznacza to, że nie można używać wyrażeń lambda z „treścią instrukcji” (tzn. Wyrażeń lambda, które używają nawiasów klamrowych) w miejscach, w których wyrażenie lambda należy przekonwertować na drzewo wyrażeń (co ma miejsce na przykład w przypadku korzystania z linq2sql) .
źródło
Nie wiedząc więcej o tym, co robisz (Linq2Objects, Linq2Entities, Linq2Sql?), Powinno to umożliwić:
źródło
.AsEnumerable()
Użyj tego przeciążenia select:
źródło
Expression<Func<Obj,Obj>>
.Obiekt zwrotny LINQ to SQL implementował
IQueryable
interfejs. Zatem dlaSelect
parametru predykatu metody należy podać tylko jedno wyrażenie lambda bez treści.Wynika to z faktu, że LINQ dla kodu SQL nie jest wykonywany wewnątrz programu, a nie po stronie zdalnej, takiej jak SQL Server lub inne. Ten leniwy typ ładowania został osiągnięty poprzez wdrożenie IQueryable, gdzie oczekiwany delegat jest zawijany w klasę typu Expression, jak poniżej.
Drzewo wyrażeń nie obsługuje wyrażenia lambda w ciele, a jego jedyne wsparcie wyrażenia lambda w jednym wierszu, jak
var id = cols.Select( col => col.id );
Więc jeśli spróbujesz, poniższy kod nie zadziała.
Poniższe będzie działać zgodnie z oczekiwaniami.
źródło
Oznacza to, że ekspresja N typu
TDelegate
, który zawiera([parameters]) => { some code };
nie może być przekształconyExpression<TDelegate>
. To reguła.Uprość swoje zapytanie. Ten, który podałeś, możesz przepisać w następujący sposób i skompilujesz:
źródło
Czy
Arr
typ podstawowyObj
? Czy istnieje klasa Obj? Twój kod działałby tylko wtedy, gdy Arr jest podstawowym typem Obj. Możesz spróbować zamiast tego:źródło
W twoim konkretnym przypadku ciało służy do utworzenia zmiennej, a przełączenie na
IEnumerable
zmusi wszystkie operacje do przetworzenia po stronie klienta, proponuję następujące rozwiązanie.Edycja: Zmień nazwę dla konwencji kodowania C #
źródło