I持っタイムアウト次のコード:私はSQL Serverプロファイラを使用してSQLをプロファイリングし、実行されたSQLをつかん奇妙なLINQ()
using (var ts = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted }))
{
ECWSDataContext dc = new ECWSDataContext();
IQueryable<Ticket> results = dc.Tickets;
Business.TicketStatistic statistic = results
.Select(r => new
{
GroupID = 1,
IsVoided = r.IsVoided ? 1 : 0,
IsWarning = r.TicketFilingTypeID == 5 ? 1 : 0,
TotalFelonies = r.TotalFelonies,
TotalMisdemeanors = r.TotalMisdemeanors,
TotalInfractions = r.TotalInfractions,
TotalOrdinances = r.TotalOrdinances,
TotalWarnings = r.TotalWarnings
})
.GroupBy(t => t.GroupID)
.Select(g => new Business.TicketStatistic()
{
TotalTickets = g.Count(),
TotalVoids = g.Sum(x => x.IsVoided),
TotalTicketWarnings = g.Sum(x => x.IsWarning),
TotalFelonies = g.Sum(x => x.TotalFelonies),
TotalMisdemeanors = g.Sum(x => x.TotalMisdemeanors),
TotalInfractions = g.Sum(x => x.TotalInfractions),
TotalOrdinances = g.Sum(x => x.TotalOrdinances),
TotalOffenseWarnings = g.Sum(x => x.TotalWarnings)
}).FirstOrDefault();
}
。予想通り、TOP 1が含まれています。SQL Management Studioで正確なSQLを実行すると、まったく時間がかかりません。それでも、コード内でタイムアウトし続けます。驚くべきことに、うまく次のような作品にそれを変える:
using (var ts = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted }))
{
ECWSDataContext dc = new ECWSDataContext();
IQueryable<Ticket> results = dc.Tickets;
var stats = results
.Select(r => new
{
GroupID = 1,
IsVoided = r.IsVoided ? 1 : 0,
IsWarning = r.TicketFilingTypeID == 5 ? 1 : 0,
TotalFelonies = r.TotalFelonies,
TotalMisdemeanors = r.TotalMisdemeanors,
TotalInfractions = r.TotalInfractions,
TotalOrdinances = r.TotalOrdinances,
TotalWarnings = r.TotalWarnings
})
.GroupBy(t => t.GroupID)
.Select(g => new Business.TicketStatistic()
{
TotalTickets = g.Count(),
TotalVoids = g.Sum(x => x.IsVoided),
TotalTicketWarnings = g.Sum(x => x.IsWarning),
TotalFelonies = g.Sum(x => x.TotalFelonies),
TotalMisdemeanors = g.Sum(x => x.TotalMisdemeanors),
TotalInfractions = g.Sum(x => x.TotalInfractions),
TotalOrdinances = g.Sum(x => x.TotalOrdinances),
TotalOffenseWarnings = g.Sum(x => x.TotalWarnings)
}).ToArray();
Business.TicketStatistic statistic = stats.FirstOrDefault();
}
は、私は今、私は今、メモリ内のコレクションにFirstOrDefault()を適用する前に結果を列挙していますことを理解しています。しかし、SQL Serverで直接最初のシナリオで同じSQL出力を実行することは問題ありませんでした。
誰かがここで何が起こっているか説明できますか?この例では、それは常に1つの行を返すグループクエリでした。 FirstOrDefault()を適用する前に列挙できることは幸運です。
SELECT TOP 1 Field1, Field2...
FROM
(
SELECT SUM(Field) as Field1, ...
FROM ...
) SUB
:しかし、将来の参考のため、そのクエリは、数千行がどの私が唯一のTOP 1.
ADDITION INFO
.FirstOrDefaultを使用してSQLを()望んでいたために何を返した場合.ToArrayを使用してSQL():
SELECT SUM(Field) as Field1, ...
FROM ...
SQL MGT Studioで直接的に実行するには、トンでも同じ結果になりました彼は同じ時間量。しかし、LINQが最初のものを実行すると、タイムアウトになります。
最初の結果を取得する前に、あなたがToArray()を呼び出したという違いがありますか? –
だから、すべての結果を元に戻すことはうまくいきますが、LINQクエリにTOP 1を追加するとタイムアウトすると言っていますか? – Jeff
これは唯一の違いです。生成されたSQLの違いは、期待どおりです。後者では、グループ化されたSQLを期待どおりに取得します。最初にToArray()を使用せずに、SELECT TOP 1ラッパーを使用してサブSELECTと同じSQLを取得します。どちらの方法でも、mgt studioで両方のSQL文を手動で実行すると、同じ結果が得られました。 –