2012-04-11 14 views
2

最後にデータをインポートして失敗を表示したかった問題が発生しました。私は2つのクエリを実行しなければならなかったので、HQLに頼ってしまったのですが、なぜこれが(正常に)LinqでNHibernateにはうまくいかないのか誰にも分かります。最大行を取得する(Linq、NHibernate)

私は書くと思います。

select JobImport.* from 
JobImportResult 
inner join (
    select Max(JobImportResultId) as JobImportResultId 
    from JobImportResult 
    group by JobImportId 
)as tbl on tbl.JobImportResultId = JobImportResult.JobImportResultId 
inner join JobImport on JobImport.JobImportId = JobImportResult.JobImportId 
where ImportFailureReasonId is not null 

HQLは結局書きました。

select jir.JobImport from JobImportResult jir where jir.Id in 
(select max(mjir.Id) from JobImportResult mjir group by mjir.JobImport) 
and jir.ImportFailureReason is not null 

動作します(私は2000行の後に中断すると思います)LINQのは

var innerQuery = Query<JobImportResult>() 
    .GroupBy(jir=>jir.JobImport) 
    .Select(jir=>jir.Max(jr=>jr.Id)); 

var innerQueryListed = innerQuery.ToList(); 

var resultQuery = Query<JobImportResult>() 
    .Where(jir => innerQueryListed.Contains(jir.Id) && jir.ImportFailureReason != null) 
    .Select(jir => jir.JobImport); 

動作しないLINQのは:(

var innerQuery = Query<JobImportResult>() 
.GroupBy(jir=>jir.JobImport) 
.Select(jir=>jir.Max(jr=>jr.Id)); 

var resultQuery = Query<JobImportResult>() 
.Where(jir => innerQuery.Contains(jir.Id) && jir.ImportFailureReason != null) 
.Select(jir => jir.JobImport); 
+0

2000行後に壊れたと言うと、エラーは何ですか? – mattytommo

+0

FYI http://stackoverflow.com/questions/656167/hitting-the-2100-parameter-limit-sql-server-when-using-contains – Mark

+0

ああ私はそれを知りませんでしたパフォーマンスはhehe :) – mattytommo

答えて

3

は、.NET 4を使用していますもしそうなら、これを試してください:

var innerQuery = Query<JobImportResult>() 
    .GroupBy(jir=>jir.JobImport) 
    .Select(jir=>jir.Max(jr=>jr.Id)) 
    .ToList(); 

var resultQuery = Query<JobImportResult>() 
    .Where(jir => innerQuery.Any(j => j == jir.Id) 
     && jir.ImportFailureReason != null) 
    .Select(jir => jir.JobImport) 
    .ToList(); //only use this if you want to resolve the query 

または.NET 3.5 ch resultQueryの部分は次のようになります。

var resultQuery = Query<JobImportResult>() 
    .Where(jir => innerQuery.Count(j => j == jir.Id) > 0 
     && jir.ImportFailureReason != null) 
    .Select(jir => jir.JobImport) 
    .ToList(); //only use this if you want to resolve the query 
+0

私は.Net 3.5を使用しています。ソリューションは動作します!.Net 4ソリューションはそれのように見えます – Mark

+0

innerQuery.Countは動作するが、元のクエリは動作しない理由を説明できますか?(これはNHの後のバージョンで修正されたバグ/機能です) – Mark

+0

ああ、うれしいです。私は元のクエリが動作しないため、あなたがToListをやっている前にContainsをやっていて、NHibernateがQueryableでContainsを実行する際に問題を抱えていると思う。私はNHibernateでいくつかの事例を見た。 IsNullOrWhiteSpaceとそのようなもののように、bes (彼らがそれを修正するまで)行うことは、最初に(ToListを使用して)クエリを解決しています。その後、元のクエリでは達成できないロジックを実行します。 – mattytommo

関連する問題