Wie kann ich am meisten aus ausdrückliche left join mit aggregate-SQL als LINQ-Abfrage
Frage
SQL:
SELECT
u.id,
u.name,
isnull(MAX(h.dateCol), '1900-01-01') dateColWithDefault
FROM universe u
LEFT JOIN history h
ON u.id=h.id
AND h.dateCol<GETDATE()-1
GROUP BY u.Id, u.name
Lösung
Eine Lösung, wenn auch eine, unterwürfig Handhabung der null-Wert im code könnte sein:
DateTime yesterday = DateTime.Jetzt.Datum.AddDays(-1);
var collection=
from u in db.Universe
select new
{
u.id,
u.name,
MaxDate =(DateTime?)
(
from h in db.History
where u.Id == h.Id
&& h.dateCol < yesterday
select h.dateCol
).Max()
};
Dies bedeutet nicht exakt die gleiche SQL, aber Sie bietet die gleiche logische Folge.Übersetzung von komplexen SQL-Abfragen in LINQ ist nicht immer einfach.
Andere Tipps
var collection=
from u in db.Universe
select new
{
u.id,
u.name,
MaxDate =(DateTime?)
(
from h in db.History
where u.Id == h.Id
&& h.dateCol < yesterday
select h.dateCol
).Max()
};
Nur youse den obigen code, und dies sollte funktionieren!
Dies ist nicht eine vollständige Antwort für Sie, aber auf der linken join-Stück, das Sie verwenden können, die DefaultIfEmpty Betreiber wie so:
var collection =
from u in db.Universe
join history in db.History on u.id = history.id into temp
from h in temp.DefaultIfEmpty()
where h.dateCol < DateTime.Now.Date.AddDays(-1)
select u.id, u.name, h.dateCol ?? '1900-01-01'
Ich hatte noch nicht die Notwendigkeit zu tun jede groupby-Befehle noch, so dass ich, dass Links nicht senden Sie den falschen Weg eingeschlagen.Zwei andere schnelle Dinge zu beachten.Ich haben nicht tatsächlich join auf zwei Parameter, obwohl wie oben, es gibt Möglichkeiten, dies zu umgehen.Auch das ??operator funktioniert wirklich gut an Stelle von isnull in SQL.
Sie gehen zu wollen, zu verwenden join into
konstruieren Sie zunächst eine Gruppe erstellen-Abfrage.
TestContext db = new TestContext(CreateSparqlTripleStore());
var q = from a in db.Album
join t in db.Track on a.Name equals t.AlbumName into tracks
select new Album{Name = a.Name, Tracks = tracks};
foreach(var album in q){
Console.WriteLine(album.Name);
foreach (Track track in album.Tracks)
{
Console.WriteLine(track.Title);
}
}