Come faccio a più elegantemente express left join con aggregazione SQL query LINQ

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

  •  08-06-2019
  •  | 
  •  

Domanda

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
È stato utile?

Soluzione

Una soluzione, anche se uno che posticipa la movimentazione del valore null per il codice, potrebbe essere:

DateTime ieri = DateTime.Ora.Data.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()
    };

Questo non produce esattamente la stessa SQL, ma non fornisce la stessa logica conseguenza.Traduzione di "complesso" in SQL query LINQ non è sempre semplice.

Altri suggerimenti

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

Solo youse il codice qui sopra e dovrebbe funzionare bene!

Questa non è una risposta completa, ma il left join pezzo che si può utilizzare il DefaultIfEmpty operatore, in questo modo:

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'

Non ho avuto la necessità di fare un groupby comandi di sicurezza, così ho lasciato che fuori non si invia la strada sbagliata.Altre due cose velocemente di nota.Sono stato in grado di effettivamente join su due parametri, anche se, come sopra, ci sono modi per ottenere intorno ad esso.Inoltre, l' ??operatore funziona davvero bene in luogo di isnull in SQL.

Si sta andando a voler utilizzare il join into costruire per creare una query di gruppo.

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);
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top