I am having an issue with this query:
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;
In English:
Please, for these "Thangs", give me their last total error count.
With the models:
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; }
}
This is a simulation of the exact issue I’m facing with my real world project. I get this error when trying to assign errors:
Exception of type
‘Antlr.Runtime.NoViableAltException’
was thrown.
[.FirstOrDefault[<>f_AnonymousType22[[System.Int32,2[[TestWeb.CSharp.Models.Thing,
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
TestWeb.CSharp, Version=1.0.0.0,
Culture=neutral,
PublicKeyToken=null],[TestWeb.CSharp.Models.ReportTask,
TestWeb.CSharp, Version=1.0.0.0,
Culture=neutral,
PublicKeyToken=null]],<>f_AnonymousType22[[System.Int32,2[[TestWeb.CSharp.Models.Thing,
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
TestWeb.CSharp, Version=1.0.0.0,
Culture=neutral,
PublicKeyToken=null],[TestWeb.CSharp.Models.ReportTask,
TestWeb.CSharp, Version=1.0.0.0,
Culture=neutral,
PublicKeyToken=null]]](.Where[TestWeb.CSharp.Models.Thing](NHibernate.Linq.NhQueryable1[TestWeb.CSharp.Models.Thing],2(t,
Quote((t, ) =>
(.Contains[System.Int32](p1, t.Id,
))), ), Quote((t, ) => (new
<>f__AnonymousType1
.FirstOrDefault[TestWeb.CSharp.Models.ReportTask](.OrderByDescending[TestWeb.CSharp.Models.ReportTask,System.Int32](.Where[TestWeb.CSharp.Models.ReportTask](NHibernate.Linq.NhQueryable1[TestWeb.CSharp.Models.ReportTask],2(<>h_TransparentIdentifier0.t.Id,
Quote((task, ) =>
(Equal(task.Thang.Id, t.Id))), ),
Quote((task, ) => (task.Id)), ), ),
))), ),
Quote((<>h__TransparentIdentifier0, )
=> (new <>f__AnonymousType2
OrElse(Equal(<>h_TransparentIdentifier0.lastTask,
NULL),
Equal(<>h_TransparentIdentifier0.lastTask.Results,
NULL)) ? p2 :
.Sum[TestWeb.CSharp.Models.ReportResult](<>h_TransparentIdentifier0.lastTask.Results,
(r, ) => (r.Errors), ), ))), ), )]
I’ve tried many other formats for this query, including:
from x in x
where y.Contains(x.Id)
select ((from ... subquery).FirstOrDefault())
This gets me farther, in that a query like this is made in 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
This is syntactically incorrect and in SQLLite, I get:
SQLite error
only a single result allowed for a SELECT that is part of an expression
In SQL Server 2008 (my real DB I use), it’s a very similar error about subqueries not allowing more than one expression.
So I feel like I’m really close to the answer but I just can’t quite get it to work. Any ideas?
PS. In LINQPad using Linq-2-SQL this query works fine.
PSS. I can’t do this query using Criteria because I suck at Criteria. Bonus points to someone who gets this baby to work in Criteria… I’m totally open to that if LINQ isn’t possible.
I ended up making my SQL query into a database View and just querying against that to prevent me from pulling my hair out with NHibernate’s LINQ implementation. If anyone wants to come back and show me the “proper” way to do this, please do!