2017-01-24 2 views
2

Ich habe Probleme mit der Konvertierung von MySQL-Abfrage in Linq-Syntax in C# (für die Verwendung von Entity Framework). MySQL-Abfrage sieht wie folgt aus:Linq Wählen Sie in

SELECT * 
FROM Availability as tableData 
WHERE ID = (
SELECT Availability.ID 
FROM Availability 
WHERE Availability.FrameID = tableData.FrameID 
ORDER BY Availability.Date DESC limit 1) 

Ich weiß nicht, wie dieser Teil FROM table AS someName zu konvertieren.

Bisher ist die einzige Lösung, die ich habe, ist roh SQL-Abfrage wie auszuführen:

dataContext.Availability.SqlQuery("SELECT * FROM Availability as tableData WHERE ID = (SELECT ID FROM Availability WHERE FrameID = tableData.FrameID ORDER BY Availability.Date DESC limit 1)").ToArray(); 

Aber es wäre schön, zu wissen, ob Linq eine solche Abfrage zur Verfügung stellen kann.

Vielen Dank im Voraus, für Ihre Antworten!

+1

Was ist der Punkt der Unterabfrage hier? –

+0

Ich brauche nur einen Datensatz (mit maximalem Datum der Einfügung) für jede FrameID – user3550149

+0

Das Ergreifen einer Entität durch eine ID wäre so einfach wie: entity = context.Table.Find (id); in Linq. Fehle ich etwas? –

Antwort

4

Wenn Sie nur aktuelle Datensatz für jeden Frame-ID benötigen, dann Gruppierung verwenden:

dataContext.Availability 
    .GroupBy(a => a.FrameID) 
    .Select(g => g.OrderByDescending(a => a.Date).FirstOrDefault()); 

Diese Abfrage erzeugt gewünschte Ergebnis, obwohl generierten SQL ein wenig anders sein wird. Es sieht wie

SELECT /* limit1 fields */ 
FROM (
    SELECT DISTINCT tableData.FrameID 
    FROM Availability as tableData) AS distinct1 
OUTER APPLY (
    SELECT TOP(1) /* project1 fields */ 
    FROM (SELECT /* extent1 fields */ 
      FROM Availability AS extent1 
      WHERE Availability.FrameID = distinct1.FrameID) AS project1 
    ORDER BY project1.Date DESC) AS limit1 

HINWEIS: First() Erweiterung nicht von EF unterstützt wird

2

all Nehmen Sie die Avilabilities, Gruppe von FrameID, bestellen Sie jede Gruppe nach Datum, nehmen Sie den ersten Eintrag jeder Gruppe. Die ToList() am Ende ruft alle Ergebnisse ab und fügt sie in eine Liste ein.

+0

als @SergeyBerezovskiy geschrieben First() wird nicht von EF unterstützt. Aber mit FirstOrDefault() funktioniert es. Vielen Dank! – user3550149

1

Ja Linq kann dies tun, aber Sie müssen eine Startsequenz haben, auf der die linq funktionieren sollte. Normalerweise hat diese Sequenz den gleichen Typ wie Ihre Tabelle, in Ihrem Fall Verfügbarkeit.

Von Ihrem SQL entnehme ich, dass jeder Datensatz in der Verfügbarkeit Tabelle zumindest Eigenschaften Id, FrameID und Datum:

class Availability 
{ 
    public int Id {get; set;} 
    public int FrameId {get; set; 
    public DateTime Date {get; set;} 
} 

Natürlich kann dies auch ein anonymer Typ sein. Die Bedeutung ist, dass Sie irgendwie eine Folge von Elementen haben, die diese Eigenschaften:

IQueryable<Availability> availabilities = ... 

Sie schrieb:

Ich brauche nur einen Datensatz (mit max Datum Insert) für jeden FrameID

So hat jede Verfügbarkeit eine FrameId, und Sie wollen für jede FrameId den Datensatz mit dem höchsten Datumswert.

Sie könnten Enumerable.GroupBy und Gruppe von FrameID verwenden

var groupsWithSameFrameId = availabilities.GroupBy(availability => availability.FrameId); 

Das Ergebnis ist eine Folge von Gruppen. Jede Gruppe enthält die Reihenfolge aller Verfügbarkeiten mit derselben FrameId. Mit anderen Worten: Wenn Sie eine Gruppe verwenden, haben Sie eine group.Key mit einem FrameId-Wert und einer Sequenz aller Verfügbarkeiten, die diesen FrameId-Wert haben.

Wir werden den group.Key nicht verwenden. Wenn Sie die Reihenfolge der Elemente in jeder Gruppe der Sortierreihenfolge nach Datum und nehmen das erste Element in absteigender Reihenfolge, werden Sie das Datum mit dem höchsten Wert haben

var recordWithMaxDateOfInsert = groupsWithSameFrameId 
    .Select(group => group.OrderByDescending(groupElement => groupElement.Date) 
    .First(); 

Aus jeder Gruppe sortiert alle Elemente der Gruppe durch absteigend Datumswert und nehmen Sie das erste Element der sortierten Gruppe.

Ergebnis: von Ihren ursprünglichen Verfügbarkeiten haben Sie für jeden Rahmen die Verfügbarkeit mit dem höchsten Wert für das Datum.