Dlaczego otrzymuję błąd:
Nie można utworzyć stałej wartości typu „Typ zamknięcia”. W tym kontekście obsługiwane są tylko typy pierwotne (na przykład Int32, String i Guid).
Kiedy próbuję wyliczyć następujące zapytanie Linq?
IEnumerable<string> searchList = GetSearchList();
using (HREntities entities = new HREntities())
{
var myList = from person in entities.vSearchPeople
where upperSearchList.All( (person.FirstName + person.LastName) .Contains).ToList();
}
Aktualizacja : Jeśli spróbuję wykonać następujące czynności, aby spróbować wyodrębnić problem, pojawia się ten sam błąd:
where upperSearchList.All(arg => arg == arg)
Więc wygląda na to, że problem dotyczy metody All, prawda? Jakieś sugestie?
źródło
Spędziłem ostatnie 6 miesięcy walcząc z tym ograniczeniem za pomocą EF 3.5 i chociaż nie jestem najmądrzejszą osobą na świecie, jestem prawie pewien, że mam coś pożytecznego do zaoferowania na ten temat.
Kod SQL wygenerowany przez powiększenie drzewa wyrażeń „w stylu OR” o wysokości 50 mil spowoduje słaby plan wykonania zapytania. Mam do czynienia z kilkoma milionami wierszy, a wpływ jest znaczący.
Znalazłem mały hack dotyczący wykonywania kodu SQL `` in '', który pomaga, jeśli szukasz tylko kilku jednostek według identyfikatora:
private IEnumerable<Entity1> getByIds(IEnumerable<int> ids) { string idList = string.Join(",", ids.ToList().ConvertAll<string>(id => id.ToString()).ToArray()); return dbContext.Entity1.Where("it.pkIDColumn IN {" + idList + "}"); }
gdzie pkIDColumn to nazwa kolumny identyfikatora klucza podstawowego tabeli Entity1.
ALE CZYTAJCIE!
To jest w porządku, ale wymaga posiadania już identyfikatorów tego, co muszę znaleźć. Czasami po prostu chcę, aby moje wyrażenia sięgały do innych relacji, a to, co mam, to kryteria tych powiązanych relacji.
Gdybym miał więcej czasu, spróbuję przedstawić to wizualnie, ale nie przestudiuję tego zdania przez chwilę: rozważ schemat z tabelami Person, GovernmentId i GovernmentIdType. Andrew Tappert (osoba) ma dwie karty identyfikacyjne (GovernmentId), jedną z Oregonu (GovernmentIdType) i jedną z Waszyngtonu (GovernmentIdType).
Teraz wygeneruj z niego edmx.
Teraz wyobraź sobie, że chcesz znaleźć wszystkie osoby o określonej wartości identyfikacyjnej, powiedzmy 1234567.
Można to osiągnąć za pomocą pojedynczego trafienia w bazie danych w ten sposób:
dbContext context = new dbContext(); string idValue = "1234567"; Expression<Func<Person,bool>> expr = person => person.GovernmentID.Any(gid => gid.gi_value.Contains(idValue)); IEnumerable<Person> people = context.Person.AsQueryable().Where(expr);
Czy widzisz tutaj podzapytanie? Wygenerowany sql użyje „złączeń” zamiast pod-zapytań, ale efekt jest taki sam. W dzisiejszych czasach serwer SQL i tak optymalizuje podzapytania pod kątem łączenia pod osłonami, ale i tak ...
Kluczem do tej pracy jest .Any wewnątrz wyrażenia.
źródło
Znalazłem przyczynę błędu (używam Framework 4.5). Problem polega na tym, że EF typ złożony, który jest przekazywany w parametrze „Contains”, nie może zostać przetłumaczony na zapytanie SQL. EF może używać w zapytaniach SQL tylko prostych typów, takich jak int, string ...
this.GetAll().Where(p => !assignedFunctions.Contains(p))
GetAll zawiera listę obiektów o typie złożonym (na przykład: „Funkcja”). Dlatego spróbuję tutaj otrzymać wystąpienie tego złożonego typu w moim zapytaniu SQL, które naturalnie nie może działać!
Jeśli mogę wyodrębnić z mojej listy parametry, które pasują do mojego wyszukiwania, mogę użyć:
var idList = assignedFunctions.Select(f => f.FunctionId); this.GetAll().Where(p => !idList.Contains(p.FunktionId))
Teraz EF nie ma już do pracy typu złożonego „Function”, ale np. Z typem prostym (long). I to działa dobrze!
źródło
Otrzymałem ten komunikat o błędzie, gdy mój obiekt tablicy używany w funkcji .All ma wartość null Po zainicjowaniu obiektu tablicy (w twoim przypadku upperSearchList) błąd zniknął Komunikat o błędzie był w tym przypadku mylący
gdzie upperSearchList.All (arg => person.someproperty.StartsWith (arg)))
źródło