LINQ NHibernate-为什么我的HAVING子句中的Column'无效?

时间:2013-02-03 19:42:59

标签: nhibernate linq-to-sql

我想获取表中的最后一个条目并将它们与另一个表连接以生成不匹配的条目。

我收到以下错误

Column is invalid in the HAVING clause 
because it is not contained in either 
an aggregate function or the GROUP BY clause

对于CFWD和Balance 运行以下

var lastEntries = from s in session.Query<Statement>()
                  group s by s.Customer.Id into grp
                  select grp.OrderByDescending(g => g.Id).First();

 var customers = session.Query<Customer>();

 var balances = from s in lastEntries 
                join c in customers on s.Customer.Id equals c.Id 
                where s.Customer.Balance !=  s.CFwd
                select s ;

 foreach (var line in balances )
 {
     ...
 }

但是,在LiNQPad中对其进行测试会产生没有错误的预期结果

var lastEntries = from s in Statements
                  group s by s.Customer.Id into grp
                  select grp.OrderByDescending(g => g.Id).First();

var customers = from s in  Customers select s;

var balances = from s in lastEntries 
       join c in Customers on s.Customer.Id equals c.Id 
       where c.Balance !=  s.CFwd 
       select s;

 balances .Dump();

更新

以下是NHibernate生成的SQL语句

select statement0_.Id as Id0_, 
statement0_.TransactionDate as Transact2_0_, 
statement0_.RefNo as RefNo0_, 
statement0_.Description as Descript4_0_, 
statement0_.BFwd as BFwd0_, 
statement0_.Amount as Amount0_, 
statement0_.CFwd as CFwd0_, 
statement0_.TransactionTypeId as Transact8_0_, 
statement0_.CustomerId as CustomerId0_ 
from Statement statement0_, Customer customer1_ 
where customer1_.Id=statement0_.CustomerId
group by statement0_.CustomerId 
having customer1_.Balance<>statement0_.AmountCFwd 

而LINQPad生成以下内容

SELECT [t5].[test], [t5].[Id], [t5].[TransactionDate], 
[t5].[CustomerId], [t5].[RefNo], [t5].[Description], 
[t5].[BFwd], [t5].[Amount], [t5].[CFwd], 
[t5].[TransactionTypeId]
FROM (
    SELECT [t1].[Id]
    FROM [Statement] AS [t0]
    INNER JOIN [Customer] AS [t1] ON [t1].[Id] = [t0].[CustomerId]
    GROUP BY [t1].[Id]
    ) AS [t2]
OUTER APPLY (
    SELECT TOP (1) 1 AS [test], [t3].[Id], [t3].[TransactionDate], 
     [t3].[CustomerId], [t3].[DocRefNo], [t3].[Description], 
     [t3].[BFwd], [t3].[Amount], [t3].[CFwd], 
     [t3].[TransactionTypeId]
    FROM [Statement] AS [t3]
    INNER JOIN [Customer] AS [t4] ON [t4].[Id] = [t3].[CustomerId]
    WHERE [t2].[Id] = [t4].[Id]
    ORDER BY [t3].[Id] DESC
    ) AS [t5]
INNER JOIN [Customer] AS [t6] ON (
    SELECT [t7].[Id]
    FROM [Customer] AS [t7]
    WHERE [t7].[Id] = [t5].[CustomerId]
    ) = [t6].[Id]
WHERE [t6].[Balance] <> [t5].[CFwd]
ORDER BY [t5].[Id] DESC

我已经尝试重新排列语句以允许分组,但似乎没有做到正确。

哪种语法可以防止错误?

2 个答案:

答案 0 :(得分:1)

事实证明我正在考虑SQL方式而不是对象。我要求的唯一声明是

var lastEntries = from s in session.Query<Statement>()
              group s by s.Customer.Id into grp
              select grp.OrderByDescending(g => g.Id).First();

并为Statement对象的所有列添加分组,如下所示

var lastEntries = from s in session.Query<Statement>()
              group s by new 
                    {
                       s.Customer
                      , s.Id
                       ...
                    } into grp
              select grp.OrderByDescending(g => g.Id).First();

答案 1 :(得分:0)

我认为这可能只是一个简单的错字。

在适用于LinqPad的示例中,您的where子句与已加入的Customers进行比较。

但是,在您的LinqToNHibernate示例中,您的where子句与s的{​​{1}}进行比较,而不是加入的客户lastEntries

所以也许对于你的NHibernate例子,你只需要做

c