Warum bekomme ich den Fehler:
Es kann kein konstanter Wert vom Typ 'Verschlusstyp' erstellt werden. In diesem Zusammenhang werden nur primitive Typen (z. B. Int32, String und Guid) unterstützt.
Wenn ich versuche, die folgende Linq-Abfrage aufzulisten?
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();
}
Update : Wenn ich Folgendes versuche, um das Problem einzugrenzen, wird der gleiche Fehler angezeigt:
where upperSearchList.All(arg => arg == arg)
Es sieht also so aus, als ob das Problem bei der All-Methode liegt, oder? Irgendwelche Vorschläge?
quelle
Ich habe die letzten 6 Monate damit verbracht, diese Einschränkung mit EF 3.5 zu bekämpfen, und obwohl ich nicht die klügste Person der Welt bin, bin ich mir ziemlich sicher, dass ich zu diesem Thema etwas Nützliches zu bieten habe.
Die SQL, die durch das Wachsen eines 50 Meilen hohen Baums von Ausdrücken im "OR-Stil" generiert wird, führt zu einem schlechten Ausführungsplan für Abfragen. Ich habe es mit ein paar Millionen Zeilen zu tun und die Auswirkungen sind erheblich.
Es gibt einen kleinen Hack, den ich gefunden habe, um ein SQL-In auszuführen, das hilft, wenn Sie nur nach einer Reihe von Entitäten anhand der ID suchen:
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 + "}"); }
Dabei ist pkIDColumn der Name Ihrer Primärschlüssel-ID-Spalte in Ihrer Entity1-Tabelle.
ABER LESEN SIE WEITER!
Das ist in Ordnung, aber es erfordert, dass ich bereits die IDs von dem habe, was ich finden muss. Manchmal möchte ich nur, dass meine Ausdrücke in andere Beziehungen hineinreichen, und was ich habe, sind Kriterien für diese verbundenen Beziehungen.
Wenn ich mehr Zeit hätte, würde ich versuchen, dies visuell darzustellen, aber ich studiere diesen Satz nicht nur einen Moment lang: Betrachten Sie ein Schema mit den Tabellen Person, GovernmentId und GovernmentIdType. Andrew Tappert (Person) hat zwei ID-Karten (GovernmentId), eine aus Oregon (GovernmentIdType) und eine aus Washington (GovernmentIdType).
Generieren Sie nun einen edmx daraus.
Stellen Sie sich nun vor, Sie möchten alle Personen mit einem bestimmten ID-Wert finden, z. B. 1234567.
Dies kann mit einem einzigen Datenbanktreffer erreicht werden:
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);
Sehen Sie die Unterabfrage hier? Die generierte SQL verwendet 'Joins' anstelle von Unterabfragen, aber der Effekt ist der gleiche. Heutzutage optimiert SQL Server Unterabfragen ohnehin in Joins unter dem Deckmantel, aber trotzdem ...
Der Schlüssel zu dieser Arbeit ist das .Any im Ausdruck.
quelle
Ich habe die Fehlerursache gefunden (ich verwende Framework 4.5). Das Problem ist, dass EF, ein komplexer Typ, der im Parameter "Enthält" übergeben wird, nicht in eine SQL-Abfrage übersetzt werden kann. EF kann in einer SQL-Abfrage nur einfache Typen wie int, string ... verwenden.
this.GetAll().Where(p => !assignedFunctions.Contains(p))
GetAll bietet eine Liste von Objekten mit einem komplexen Typ (zum Beispiel: "Funktion"). Daher würde ich hier versuchen, eine Instanz dieses komplexen Typs in meiner SQL-Abfrage zu erhalten, die natürlich nicht funktionieren kann!
Wenn ich aus meiner Liste Parameter extrahieren kann, die für meine Suche geeignet sind, kann ich Folgendes verwenden:
var idList = assignedFunctions.Select(f => f.FunctionId); this.GetAll().Where(p => !idList.Contains(p.FunktionId))
Jetzt hat EF nicht mehr den komplexen Typ "Funktion" zum Arbeiten, sondern zB mit einem einfachen Typ (lang). Und das funktioniert gut!
quelle
Ich habe diese Fehlermeldung erhalten, wenn mein in der .All-Funktion verwendetes Array-Objekt null ist. Nachdem ich das Array-Objekt initialisiert habe (in Ihrem Fall die obere Suchliste), ist der Fehler verschwunden. Die Fehlermeldung war in diesem Fall irreführend
Dabei ist UpperSearchList.All (arg => person.someproperty.StartsWith (arg)))
quelle