2011-05-26 47 views
0

我有這個查詢的問題:NHibernate的3.1 LINQ子查詢和投影問題

var idsToFetch = new int[] {1, 2}; 

var q = from t in session.Query<Thing>() 
     where idsToFetch.Contains(t.Id) 
     let lastTask = (from task in session.Query<ReportTask>() 
         where task.Thang.Id == t.Id 
         orderby task.Id descending 
         select task).FirstOrDefault() 
     select new { 
      Id = t.Id, 
      Errors = lastTask.Results.Sum(r => r.Errors) 
     }; 

var errors = q.FirstOrDefault().Errors; 

英文:

Please, for these "Thangs", give me their last total error count. 

隨着車型:

public class Thing 
{ 
    public virtual int Id { get; set; } 
} 

public class ReportTask 
{ 
    public virtual int Id { get; set; } 
    public virtual Thing Thang { get; set; } 
    public virtual ICollection<ReportResult> Results { get; set; } 
} 

public class ReportResult 
{ 
    public virtual int Id { get; set; } 
    public virtual ReportTask Task { get; set; } 
    public virtual int Errors { get; set; } 
} 

這是我真實世界項目面臨的確切問題的模擬。我在嘗試分配errors當這個錯誤:

類型的異常「Antlr.Runtime.NoViableAltException」 被拋出。 [.FirstOrDefault [<> F_ AnonymousType2 2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]](.Select[<>f__AnonymousType1 -2 - [[TestWeb.CSharp.Models.Thing, TestWeb.CSharp,版本= 1.0.0.0, 文化=中性 公鑰=空],[TestWeb.CSharp.Models .ReportTask, TestWeb.CSharp,版本= 1.0.0.0, 文化=中性 公鑰=空],<>˚F _AnonymousType2 2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]](.Select[TestWeb.CSharp.Models.Thing,<>f__AnonymousType1 -2 - [[TestWeb.CSharp.Models.Thing, TestWeb.CSharp,版本= 1.0.0.0, Culture = neutral, PublicKeyToken = null],[TestWeb.CSharp.Models.ReportTask, TestWeb.CSharp,Version = 1.0.0.0, Culture = ne utral, PublicKeyToken = null]]](。其中[TestWeb.CSharp.Models.Thing](NHibernate.Linq.NhQueryable 1[TestWeb.CSharp.Models.Thing], Quote((t,) => (.Contains[System.Int32](p1, t.Id, ))),), Quote((t,) => (new <>f__AnonymousType1 2(t, .FirstOrDefault [TestWeb.CSharp.Models.ReportTask](。OrderByDescending [TestWeb。 CSharp.Models.ReportTask,System.Int32](其中[TestWeb.CSharp.Models.ReportTask](NHibernate.Linq.NhQueryable 1[TestWeb.CSharp.Models.ReportTask], Quote((task,) => (Equal(task.Thang.Id, t.Id))),), Quote((task,) => (task.Id)),),), ))),), Quote((<>h__TransparentIdentifier0,) => (new <>f__AnonymousType2 2(<> H_ TransparentIdentifier0.t.Id, OrElse運算(等於(<>ħ _TransparentIdentifier0.lastTask, NULL), Equal(<> h_ TransparentIdentifier0.lastTask.Results, NULL))? P2: .SUM [TestWeb.CSharp.Models.ReportResult](<>ħ _TransparentIdentifier0.lastTask.Results, (R,)=>(r.Errors),),))),),)]

我試過很多其他格式此查詢,包括:

from x in x 
where y.Contains(x.Id) 
select ((from ... subquery).FirstOrDefault()) 

這讓我越來越遠,在這樣的查詢在SQL製作:

select (select 
      thing0_.Id, 
      (select cast(sum(results2_.Errors) as INTEGER) 
      from "ReportResult" results2_ 
      where reporttask1_.Id=results2_.ReportTask_id) 
     from "ReportTask" reporttask1_ 
     where reporttask1_.Thang_id=thing0_.Id 
     order by reporttask1_.Id desc) as col_0_0_ 
from "Thing" thing0_ 
where thing0_.Id in (1, 2) 
limit 1 

這是較好語法ically不正確和SQLLite,我得到:

SQLite的錯誤 只允許一個SELECT一個結果是一個表達式

在SQL Server 2008的一部分(我真正的DB我使用),對於不允許多個表達式的子查詢,這是一個非常類似的錯誤。

所以我覺得我真的很接近答案,但我不能完全實現它的工作。有任何想法嗎?

PS。在使用Linq-2-SQL的LINQPad中,此查詢正常工作。

PSS。我不能使用Criteria來做這個查詢,因爲我在Criteria中吮吸。獎金指向得到這個寶寶在Criteria中工作的人......如果LINQ不可能,我完全接受這一點。

回答

0

我最終把我的SQL查詢放入一個數據庫視圖,只是查詢,以防止我用NHibernate的LINQ實現拉我的頭髮。如果有人想回來並向我展示「正確」的方式來做到這一點,請做!