2012-06-13 6 views
13

Ich habe das gleiche Problem hier gepostet: LINQ to Entities group-by failure using .date.NET LINQ zu Entitäten Gruppe nach Datum (Tag)

Doch die Antwort ist nicht 100% richtig. Es funktioniert in allen Fällen, außer wenn verschiedene Zeitzonen verwendet werden. Wenn verschiedene Zeitzonen verwendet werden, werden auch Zeitzonen gruppiert. Warum? Ich habe es geschafft, dies mit vielen Entity-Funktionen zu umgehen.

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, 
    ... 
}); 

Gibt es jemanden da draußen, der weiß, wie man das richtig macht? Dieser Code ist so hässlich und wahrscheinlich sehr ineffizient.

UPDATE (Warnung):
Ich erkannte auch, dass die Funktion EntityFunctions.CreateDateTime von einem Fehler leidet. Es ist nicht kompatibel mit Schaltjahren, wie in diesem Jahr. 29. Februar 2012 wird eine Ausnahme werfen.

+10

Hässlicher Code ist nicht unbedingt ineffizienter Code. –

+0

ja, aber solch eine einfache Operation sollte in der Lage sein, einfacher zu schreiben? – Zeezer

+0

Nicht unbedingt. Denken Sie daran, dass Linq to Entities C# in SQL konvertieren muss. Das bedeutet, dass es viele Einschränkungen für die Vorgehensweise gibt, da es keinen SQL gibt, der den Vorgang unterstützt. Die EntityFunctions gibt es speziell, um mit diesen Einschränkungen umzugehen, also müssen Sie sie verwenden, wenn Sie wollen, was sie tun. –

Antwort

0

Sie können UTC DateTime und trunkate die Zeit danach verwenden.

+0

Sie meinen die DateTime Funktion ToUniversalTime()? Dies funktioniert nicht in Linken zu Entitäten. Sie können nur wenige Funktionen und Eigenschaften in linq zu Entitäten verwenden. – Zeezer

+0

LinqToEntity versuchen, Ihre Anfrage in SQL-Abfrage zu konvertieren. Es kann ToUniversalTime() nicht in Sql übersetzen. Ich würde vorschlagen, dass Sie alle Daten zuerst (.ToList() zum Beispiel) und irgendwelche Sachen mit der Sammlung der Daten machen. In diesem Fall können Sie die Funktion ToUTCTime() in der Linq-Abfrage verwenden. –

+0

Ich habe es mit riesigen Tabellen und komplexen Statistiken zu tun. Alle Daten zuerst zu bekommen, hat Auswirkungen auf die Leistung, die ich nicht eingehen möchte. – Zeezer