3 Stimmen

Nach einem Feld sortieren, das eine Navigations-Eigenschaft zu einer Entität ist - Linq zu Entity

Ich habe ein Szenario, in dem ich nach einer Spalte sortieren muss, die eine Navigationsproperty für die Benutzerentität in meinem EF-Modell ist.

Die Entitäten: Benutzer --> Länder 1:n Beziehung

Ein einfacher SQL-Abfrage wäre wie folgt:

SELECT UserId, u.Name, c.Name
FROM users u join countries c on u.CountryId = c.CountryId
ORDER BY c.Name asc;

Also habe ich versucht, die obige SQL-Abfrage mit Linq to Entities wie folgt nachzubilden - (Lazy Loading ist aktiviert)

entities.users.OrderBy(feld => feld.country.Name).ToList();

Aber diese Abfrage gibt meine Länder nicht nach ihrem Namen sortiert zurück, wie es die native SQL-Abfrage oben tut.

Ich bin jedoch ein wenig weitergegangen und habe folgendes gemacht:

var aufgelisteteBenutzer = entities.users.AsEnumerable();
benutzer = aufgelisteteBenutzer.OrderBy(felder => felder.country.Name).ToList();

Aber das Sortieren des aufgelisteten Benutzers für etwa 50 Datensätze dauerte ca. 7 Sekunden.

Gibt es einen besseren Weg, wie man das Aufzählen vermeiden kann, ohne einen anonymen Typ zurückzugeben?

Danke

EDIT

Ich habe einfach vergessen zu erwähnen, dass der EF-Anbieter ein MySQL-Anbieter ist und nicht MS SQL. Tatsächlich habe ich gerade die gleiche Abfrage auf einer replizierten Datenbank in MS SQL ausprobiert und die Abfrage funktioniert gut, d.h. der Ländername ist korrekt sortiert, also sieht es so aus, als ob ich keine andere Möglichkeit habe, als das Ergebnis von MySQL zu bekommen und das Sortieren im Arbeitsspeicher am aufzählbaren Objekt auszuführen.

6voto

Eranga Punkte 31803
var enumeratedUsers = entities.users.AsEnumerable();
users = enumeratedUsers.OrderBy(fields => fields.country.Name).ToList();

Dies ist LINQ für Objekte, nicht LINQ für Entitäten.

Die oben stehende Order By-Klausel ruft OrderBy aus Enumerable auf

Das bedeutet, dass die Sortierung im Speicher durchgeführt wird. Daher wird es lange dauern

Bearbeiten

Es scheint sich um ein MySQL-bezogenes Problem zu handeln

Sie können etwas Ähnliches wie dies versuchen.

        var users = from user in entities.users
                          join country in entities.Country on user.CountryId equals country.Id
                          orderby country.Name
                          select user;

3voto

Jin-Wook Chung Punkte 4104

entities.users.OrderBy(field => field.country.Name).ToList();

Aber diese Abfrage gibt meine Länder nicht nach ihrem Namen sortiert zurück, wie es die native SQL-Abfrage oben tut.

Ja, es gibt keine Länder zurück, sondern nur Benutzer, die nach dem Namen des Landes sortiert sind. Wenn diese Abfrage ausgeführt wird, wird der folgende SQL an die DB gesendet.

SELECT u.*
FROM users u join countries c on u.CountryId = c.CountryId
ORDER BY c.Name asc;

Wie Sie sehen können, enthält das Ergebnis keine Felder von Ländern. Wie von Ihnen erwähnt, erfolgt das Lazy Loading, um sie bei Bedarf zu laden. Zu diesem Zeitpunkt werden die Länder so geordnet, wie Sie sie über das Lazy Loading aufrufen. Sie können auf Länder über die Local-Eigenschaft eines Entity-Sets zugreifen.

An diesem Punkt wird Ihnen gesagt, dass Sie Benutzer nach dem Namen des Landes und auch Länder nach dem Namen sortiert haben möchten, müssen Sie das eagerly loading wie von @Dennis erwähnt verwenden:

entities.users.Include["country"].OrderBy(field => field.country.Name).ToList();

Dies wird in das folgende SQL umgewandelt.

SELECT u.*, c.*
FROM users u join countries c on u.CountryId = c.CountryId
ORDER BY c.Name asc;

0voto

Dennis Traub Punkte 48712

Hast du versucht, Include zu verwenden?

entities.users.Include["country"].OrderBy(field => field.country.Name).ToList();

0voto

Ryan Punkte 265

LÖSUNG

Da ich beide Spalten in den Tabellen Länder und Benutzer mit dem Namen Name hatte, hat der MySQL Connector dieses Ergebnis generiert, als ORDER BY country.Name ausgeführt wurde:

SELECT `Extent1`.`Username`,  `Extent1`.`Name`,  `Extent1`.`Surname`, `Extent1`.`CountryId`
FROM `users` AS `Extent1` INNER JOIN `countries` AS `Extent2` ON `Extent1`.`CountryId` = `Extent2`.`CountryId`
ORDER BY `Name` ASC

Deshalb führt dies zu einer Sortierung nach users.Name und nicht nach countries.Name

Allerdings hat MySQL die Version 6.4.3 des .NET Connectors veröffentlicht, die eine Reihe von Problemen gelöst hat, darunter:

Wir haben auch einige SQL-Generierungsverbesserungen im Zusammenhang mit unserem Entity Framework-Provider eingefügt. Quelle: http://forums.mysql.com/read.php?3,425992

Vielen Dank für all Ihre Hilfe. Ich habe versucht, so klar wie möglich zu sein, um anderen zu helfen, die möglicherweise auf das gleiche Problem stoßen könnten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X