Hoe kan ek die meeste elegant uitdruklike links te sluit met totaal SQL as LINQ navraag

StackOverflow https://stackoverflow.com/questions/832

  •  08-06-2019
  •  | 
  •  

Vra

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
Was dit nuttig?

Oplossing

'n oplossing, al is dit een wat uitstel hantering van die nul waarde aan die kode, kan wees:

  

Datum tyd gister = DateTime.Now.Date.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()
    };

Dit produseer nie presies dieselfde SQL, maar dieselfde logiese gevolg voorsien. Vertaling "kompleks" SQL navrae te LINQ is nie altyd maklik.

Ander wenke

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()
    };

Just youse bogenoemde kode en dit behoort reg te werk!

Dit is nie 'n volledige antwoord vir jou, maar aan die linkerkant sluit stuk kan jy die DefaultIfEmpty operateur gebruik soos 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'

Ek het nie die behoefte om te doen enige groupby beveel nie, so ek het dit uit as om jou op die verkeerde pad stuur nie. Twee ander vinnige dinge om op te let. Ek het nie in staat is om werklik te sluit op twee parameters is hoewel soos hierbo is daar maniere om dit te kry. Ook die ?? operateur werk baie goed in die plek van die isnull in SQL.

Jy gaan wil die join into konstruk gebruik om 'n groep navraag te skep.

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);
    }
}
Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top