IQueryableクエリ文のOrderByDescending()拡張メソッド使用上の注意点
4842 ワード
目的:構造物の下のすべてのゲートウェイの最新診断結果を照会する.
1.正しいクエリ(診断時の逆)
クエリの結果:
構造下の各ゲートウェイの最新診断結果.
2.エラークエリ(ソートの目的が達成されていない)
次のコードに示すように、クエリ文の「.OrderByDescending()」を下の位置に調整します.
クエリの結果:
所期の結果に達していない場合、最も遅い診断記録であるか、履歴診断のいずれかの記録である可能性がある.
【まとめ】
IQueryableクエリ文でOrderByDescending()拡張メソッドを使用する場合は、次の点に注意してください.
結果セットを時系列に並べ替える必要がある場合は、「OrderByDescending()」拡張メソッドを後にする必要がある.
前に置くと、LINQ文変換後のSQL文には「order by」のソート条件がないため、逆の効果は得られない.
1.正しいクエリ(診断時の逆)
var query = queryDiag.GroupBy(g => new {g.dtuId, g.dtuNo, g.dtuDesp})
.Select(s =>
s.GroupBy(r => r.diagTime)
.Select(e => new
{
s.Key.dtuId,
s.Key.dtuNo,
s.Key.dtuDesp,
diagTime = e.Key,
cpuRatio = e.Where(w => w.diagName == iDAUDiagEntity.CpuRatio)
.Select(l => l.diagResult).FirstOrDefault(),
memoryRatio = e.Where(w => w.diagName == iDAUDiagEntity.MemoryRatio)
.Select(l => l.diagResult).FirstOrDefault(),
flashRatio = e.Where(w => w.diagName == iDAUDiagEntity.FlashRatio)
.Select(l => l.diagResult).FirstOrDefault(),
sdRatio = e.Where(w => w.diagName == iDAUDiagEntity.SdRatio)
.Select(l => l.diagResult).FirstOrDefault(),
gatewayWorkDuration = e.Where(w => w.diagName == iDAUDiagEntity.GatewayWorkDuration)
.Select(l => l.diagResult).FirstOrDefault(),
serverWorkDuration = e.Where(w => w.diagName == iDAUDiagEntity.ServerWorkDuration)
.Select(l => l.diagResult).FirstOrDefault(),
nodesCount = e.Select(l => l.nodesCount).FirstOrDefault()
}).OrderByDescending(o => o.diagTime).FirstOrDefault());
クエリの結果:
構造下の各ゲートウェイの最新診断結果.
2.エラークエリ(ソートの目的が達成されていない)
次のコードに示すように、クエリ文の「.OrderByDescending()」を下の位置に調整します.
var query = queryDiag.GroupBy(g => new {g.dtuId, g.dtuNo, g.dtuDesp})
.Select(s =>
s.OrderByDescending(o => o.diagTime).GroupBy(r => r.diagTime)
.Select(e => new
{
s.Key.dtuId,
s.Key.dtuNo,
s.Key.dtuDesp,
diagTime = e.Key,
cpuRatio = e.Where(w => w.diagName == iDAUDiagEntity.CpuRatio)
.Select(l => l.diagResult).FirstOrDefault(),
memoryRatio = e.Where(w => w.diagName == iDAUDiagEntity.MemoryRatio)
.Select(l => l.diagResult).FirstOrDefault(),
flashRatio = e.Where(w => w.diagName == iDAUDiagEntity.FlashRatio)
.Select(l => l.diagResult).FirstOrDefault(),
sdRatio = e.Where(w => w.diagName == iDAUDiagEntity.SdRatio)
.Select(l => l.diagResult).FirstOrDefault(),
gatewayWorkDuration = e.Where(w => w.diagName == iDAUDiagEntity.GatewayWorkDuration)
.Select(l => l.diagResult).FirstOrDefault(),
serverWorkDuration = e.Where(w => w.diagName == iDAUDiagEntity.ServerWorkDuration)
.Select(l => l.diagResult).FirstOrDefault(),
nodesCount = e.Select(l => l.nodesCount).FirstOrDefault()
}).FirstOrDefault());
クエリの結果:
所期の結果に達していない場合、最も遅い診断記録であるか、履歴診断のいずれかの記録である可能性がある.
【まとめ】
IQueryableクエリ文でOrderByDescending()拡張メソッドを使用する場合は、次の点に注意してください.
結果セットを時系列に並べ替える必要がある場合は、「OrderByDescending()」拡張メソッドを後にする必要がある.
前に置くと、LINQ文変換後のSQL文には「order by」のソート条件がないため、逆の効果は得られない.