Ich habe diese Linq-Abfrage:
private void GetReceivedInvoiceTasks(User user, List<Task> tasks)
{
var areaIds = user.Areas.Select(x => x.AreaId).ToArray();
var taskList = from i in _db.Invoices
join a in _db.Areas on i.AreaId equals a.AreaId
where i.Status == InvoiceStatuses.Received && areaIds.Contains(a.AreaId)
select new Task {
LinkText = string.Format(Invoice {0} has been received from {1}, i.InvoiceNumber, i.Organisation.Name),
Link = Views.Edit
};
}
Es hat jedoch Probleme. Ich versuche Aufgaben zu erstellen. Für jede neue Aufgabe ist es in Ordnung, wenn ich den Linktext auf eine konstante Zeichenfolge wie "Hallo" setze. Oben versuche ich jedoch, den Eigenschaftslinktext unter Verwendung der Eigenschaften der Rechnung zu erstellen.
Ich erhalte diesen Fehler:
base {System.SystemException} = {"LINQ to Entities erkennt die Methode 'System.String Format (System.String, System.Object, System.Object)' nicht und diese Methode kann nicht in einen Speicherausdruck übersetzt werden." }}
Weiß jemand warum? Kennt jemand eine alternative Möglichkeit, dies zu tun, damit es funktioniert?
linq
entity-framework
linq-to-entities
AnonyMouse
quelle
quelle
Antworten:
Entity Framework versucht, Ihre Projektion auf der SQL-Seite auszuführen, für die es keine Entsprechung gibt
string.Format
. Verwenden SieAsEnumerable()
diese Option , um die Auswertung dieses Teils mit Linq to Objects zu erzwingen.Basierend auf der vorherigen Antwort, die ich Ihnen gegeben habe, würde ich Ihre Anfrage wie folgt umstrukturieren:
Ich sehe auch, dass Sie verwandte Entitäten in der Abfrage (
Organisation.Name
) verwenden. Stellen Sie sicher, dass SieInclude
Ihrer Abfrage die richtigen hinzufügen , oder materialisieren Sie diese Eigenschaften speziell für die spätere Verwendung, dh:quelle
IQueryable
ergibt sich ausIEnumerable
der Haupt Ähnlichkeit ist , dass , wenn Sie Ihre Abfrage machen es in seiner Sprache in die Datenbank - Engine geschrieben wird, ist die dünne Moment , in dem Sie C # sagen , die Daten auf dem Server (nicht Client - Seite) oder zu sagen , SQL Griff zu handhaben Daten.Wenn Sie also sagen
IEnumerable.ToString()
, erhält C # die Datenerfassung und ruftToString()
das Objekt auf. Wenn Sie jedoch sagen, dassIQueryable.ToString()
C # SQL anweist,ToString()
das Objekt aufzurufen , gibt es in SQL keine solche Methode.Der Nachteil ist, dass beim Verarbeiten von Daten in C # die gesamte Sammlung, die Sie durchsuchen, im Speicher erstellt werden muss, bevor C # die Filter anwendet.
Am effizientesten ist es, die Abfrage wie
IQueryable
bei allen Filtern durchzuführen, die Sie anwenden können.Bauen Sie es dann im Speicher auf und formatieren Sie die Daten in C #.
quelle
SQL weiß zwar nicht, was mit einem zu tun ist
string.Format
, kann jedoch eine Zeichenfolgenverkettung durchführen.Wenn Sie den folgenden Code ausführen, sollten Sie die Daten erhalten, nach denen Sie suchen.
Sobald Sie die Abfrage tatsächlich ausgeführt haben, sollte dies geringfügig schneller sein als die Verwendung
AsEnumerable
(zumindest habe ich dies in meinem eigenen Code gefunden, nachdem ich denselben ursprünglichen Fehler wie Sie hatte). Wenn Sie mit C # etwas Komplexeres machen, müssen Sie es trotzdem verwendenAsEnumerable
.quelle
AsEnumerable()
wesentlich effizienter sein. Vermeiden SieAsEnumerable()
undToList()
bis Sie wirklich alle Ergebnisse in Erinnerung behalten möchten.