Подвопрос и проекция NHibernate 3.1 LINQ - PullRequest
0 голосов
/ 26 мая 2011

У меня проблема с этим запросом:

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, Culture = нейтрально, PublicKeyToken = NULL], [TestWeb.CSharp.Models.ReportTask, TestWeb.CSharp, версия = 1.0.0.0, Culture = нейтрально, PublicKeyToken = NULL]], <> е _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 = нейтрально, PublicKeyToken = NULL], [TestWeb.CSharp.Models.ReportTask, TestWeb.CSharp, версия = 1.0.0.0, Culture = нейтрально, 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 (т, .FirstOrDefault [TestWeb.CSharp.Models.ReportTask] (. OrderByDescending [TestWeb.CSharp.Models.ReportTask, System.Int32] (. Там, где [TestWeb.CSharp.Models.ReportTask] (NHibernate.Linq.NhQueryable * 1 019 * 2 ( <> h_ TransparentIdentifier0.t.Id, OrElse (Equal (<> ч _TransparentIdentifier0.lastTask, НОЛЬ), Равно (<> H_ TransparentIdentifier0.lastTask.Results, НОЛЬ)) ? р2: .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

Это синтаксически неверно, и в SQLLite я получаю:

Ошибка SQLite для SELECT допускается только один результат, являющийся частью выражения

В SQL Server 2008 (моя настоящая БД, которую я использую) очень похожа ошибка, связанная с тем, что подзапросы не допускают более одного выражения.

Так что я чувствую, что я действительно близок к ответу, но я просто не могу заставить его работать. Есть идеи?

PS. В LINQPad, использующем Linq-2-SQL, этот запрос работает нормально.

PSS. Я не могу сделать этот запрос, используя Criteria, потому что я сосу на Критерии. Бонус указывает на кого-то, кто заставляет этого ребенка работать в Критериях ... Я полностью открыт для этого, если LINQ невозможен.

1 Ответ

0 голосов
/ 01 июня 2011

В итоге я превратил свой SQL-запрос в представление базы данных и просто начал опрашивать его, чтобы я не выдернул свои волосы с помощью реализации LINQ от NHibernate. Если кто-то хочет вернуться и показать мне «правильный» способ сделать это, пожалуйста, сделайте!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...