¿Cómo puedo más elegante de expresar left join con agregado de SQL como de consulta de LINQ

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

  •  08-06-2019
  •  | 
  •  

Pregunta

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
¿Fue útil?

Solución

Una solución, aunque sea uno que difiere de la manipulación del valor nulo para el código, podría ser:

DateTime ayer = DateTime.Ahora.Fecha.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()
    };

Esto no producen exactamente el mismo SQL, pero no proporciona el mismo resultado lógico.La traducción de "complejo" de SQL consultas de LINQ no siempre es sencillo.

Otros consejos

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

Sólo youse el código anterior y esto debería funcionar bien!

Esto no es una respuesta completa para usted, pero en el left join pieza puede utilizar el defaultifempty junto operador así:

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'

No he tenido la necesidad de hacer cualquier groupby comandos sin embargo, así que dejó que fuera como para no llevarte por el mal camino.Otras dos cosas rápidas para nota.He sido incapaz de vincularse en dos parámetros, aunque como en el anterior, hay maneras de conseguir alrededor de él.También, el ??operador que funciona realmente bien en lugar de la isnull en SQL.

Usted va a querer usar el join into construir para crear una consulta de grupo.

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);
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top