Ich habe Probleme mit einer in LINQ und Lambda geschriebenen Abfrage. Bisher bekomme ich viele Fehler. Hier ist mein Code:
int id = 1;
var query = database.Posts.Join(database.Post_Metas,
post => database.Posts.Where(x => x.ID == id),
meta => database.Post_Metas.Where(x => x.Post_ID == id),
(post, meta) => new { Post = post, Meta = meta });
Ich bin neu in der Verwendung von LINQ, daher bin ich mir nicht sicher, ob diese Abfrage korrekt ist.
Antworten:
Ich finde, wenn Sie mit der SQL-Syntax vertraut sind, ist die Verwendung der LINQ-Abfragesyntax viel klarer, natürlicher und erleichtert das Erkennen von Fehlern:
Wenn Sie sich jedoch wirklich für die Verwendung von Lambdas interessieren, ist Ihre Syntax ziemlich unterschiedlich. Hier ist dieselbe Abfrage unter Verwendung der LINQ-Erweiterungsmethoden:
quelle
lambda
und ist Zitat einfach zu bedienen und zu verstehenSie könnten damit zwei Wege gehen. Mit LINQPad (von unschätzbarem Wert, wenn Sie neu in LINQ sind) und einer Dummy-Datenbank habe ich die folgenden Abfragen erstellt:
oder
In diesem speziellen Fall denke ich, dass die LINQ-Syntax sauberer ist (ich wechsle zwischen den beiden, je nachdem, welche am einfachsten zu lesen ist).
Ich möchte jedoch darauf hinweisen, dass Sie, wenn Sie geeignete Fremdschlüssel in Ihrer Datenbank haben (zwischen post und post_meta), wahrscheinlich keinen expliziten Join benötigen, es sei denn, Sie versuchen, eine große Anzahl von Datensätzen zu laden . Ihr Beispiel scheint darauf hinzudeuten, dass Sie versuchen, einen einzelnen Beitrag und seine Metadaten zu laden. Angenommen, es gibt viele post_meta-Datensätze für jeden Beitrag, dann können Sie Folgendes tun:
Wenn Sie das n + 1-Problem vermeiden möchten, können Sie LINQ explizit an SQL anweisen, alle zugehörigen Elemente auf einmal zu laden (obwohl dies ein fortgeschrittenes Thema sein kann, wenn Sie mit L2S besser vertraut sind). Im folgenden Beispiel heißt es: "Wenn Sie einen Beitrag laden, laden Sie auch alle ihm zugeordneten Datensätze über den Fremdschlüssel, der durch die Eigenschaft 'Post_metas' dargestellt wird."
Es ist möglich, viele
LoadWith
Anrufe mit einem einzigen SatzDataLoadOptions
für denselben Typ oder mit vielen verschiedenen Typen zu tätigen . Wenn Sie dies jedoch häufig tun, möchten Sie möglicherweise nur das Caching in Betracht ziehen.quelle
Daniel hat eine gute Erklärung für die Syntaxbeziehungen, aber ich habe dieses Dokument für mein Team zusammengestellt, um es für sie etwas einfacher zu verstehen. Hoffe das hilft jemandem
quelle
Post_ID
Feld im zweiten Aliasmeta => meta.Post_ID
. In dem Beispiel in dieser Abbildung wird derg.id
Teil der ursprünglichen select-AnweisungJOIN gStatus g on g.id
nicht im endgültigen Lambda-Ausdruck repliziert.public class IdHolder{ int id }
dann dieses Objekt im gStatus verwendetList<IdHolder> gStatus = new List<IdHolder>(); gStatus.add(new IdHolder(){id = 7}); gStatus.add(new IdHolder(){id = 8});
hätte, hätte es die Linq so geändert, dasst =>t.value.TaskStatusId, g=>g.id
diese Änderung sinnvoll ist.Ihre Schlüsselauswahl ist falsch. Sie sollten ein Objekt vom Typ der betreffenden Tabelle nehmen und den Schlüssel zurückgeben, der im Join verwendet werden soll. Ich denke du meinst das:
Sie können die where-Klausel anschließend anwenden, nicht als Teil der Schlüsselauswahl.
quelle
Posting, weil ich beim Starten von LINQ + EntityFramework einen Tag lang auf diese Beispiele gestarrt habe.
Wenn Sie EntityFramework verwenden und eine Navigationseigenschaft
Meta
für Ihr ModellobjektPost
eingerichtet haben, ist dies sehr einfach. Worauf warten Sie, wenn Sie eine Entität verwenden und diese Navigationseigenschaft nicht haben?Wenn Sie zuerst Code ausführen, richten Sie die Eigenschaft folgendermaßen ein:
quelle
Ich habe so etwas gemacht;
quelle
Es könnte so etwas sein
quelle
1 entspricht 1 zwei verschiedenen Tabellenverknüpfungen
quelle
Diese linq-Abfrage sollte für Sie funktionieren. Es werden alle Beiträge mit Post-Meta abgerufen.
Äquivalente SQL-Abfrage
quelle