2012-06-13 9 views
13

Tengo el mismo problema publicada aquí: LINQ to Entities group-by failure using .date.NET LINQ al grupo de entidades por fecha (día)

Sin embargo, la respuesta no es 100% correcto. Funciona en todos los casos, excepto cuando se usan diferentes zonas horarias. Cuando se usan diferentes zonas horarias, también se agrupa en zonas horarias. ¿Por qué? Logré omitir esto al usar muchas funciones de entidad.

int localOffset= Convert.ToInt32(
    TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).TotalMinutes); 

var results = (
    from perfEntry in db.entry 
    where (....) 
    select new { 
     perfEntry.Operation, perfEntry.Duration, 
     localTime = EntityFunctions.AddMinutes(perfEntry.Start, 
      localOffset - EntityFunctions.GetTotalOffsetMinutes(
       perfEntry.Start)) 
    } 
).GroupBy(x => new { 
    Time = EntityFunctions.TruncateTime(
     EntityFunctions.CreateDateTime(x.localTime.Value.Year, 
      x.localTime.Value.Month, x.localTime.Value.Day, 0, 0, 0)), 
    x.Operation } 
).OrderByDescending(a => a.Key). 
Select(g => new { 
    Time = g.Key.Time, 
    ... 
}); 

¿Hay alguien que sepa cómo hacerlo de la manera correcta? Este código es tan feo y probablemente muy ineficiente.

ACTUALIZACIÓN (advertencia):
También me di cuenta de que la función EntityFunctions.CreateDateTime sufre de un error. No es compatible con los años bisiestos, como este año. 29 de febrero de 2012 lanzará una excepción.

+10

El código feo no es necesariamente un código ineficiente. –

+0

sí, pero una operación tan simple debería poder escribir de una manera más fácil? – Zeezer

+0

No necesariamente. Recuerde que Linq to Entities debe convertir C# en SQL, lo que significa que tiene muchas restricciones sobre lo que puede hacer con él, porque no hay SQL que admita la operación. EntityFunctions está específicamente para lidiar con estas limitaciones, por lo que debe usarlas si quiere lo que hace. –

Respuesta

0

Puede usar UTC DateTime y truncar la hora posterior.

+0

¿Quiere decir la función DateTime ToUniversalTime()? Esto no funciona en linq para las entidades. Solo puede usar algunas funciones y propiedades en linq para entidades. – Zeezer

+0

LinqToEntity intente convertir su solicitud a la consulta sql. No puede traducir ToUniversalTime() a Sql. Te sugiero que obtengas todos los datos primero (.ToList() por ejemplo) y hagas cualquier cosa con la recopilación de los datos. En el caso, puede usar la función ToUTCTime() en la consulta Linq. –

+0

Estoy lidiando con tablas enormes y estadísticas complejas. Obtener todos los datos primero tendrá un impacto en el rendimiento que no estoy dispuesto a tomar. – Zeezer