2013-02-03 61 views
0

我想獲取表格中的最後一個條目,並將它們與另一個表格連接起來以生成不匹配的條目。LINQ NHibernate-爲什麼我得到列在HAVING子句中無效?

我收到以下錯誤

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

兩個CFWD和平衡 運行以下

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 

我試圖重新安排語句允許分組和不似乎修正它。

哪個是可以防止錯誤的正確語法?

+0

當您在LINQPad測試,你運行它針對同一數據庫? – Nathan

+0

是的。我複製了LINQPad中的語句,並用NHibernate替換替換了複數表名。 – kagundajm

+0

另一件可能有用的事情是發佈生成的底層SQL查詢。 http://stackoverflow.com/questions/129133/how-do-i-view-the-sql-that-is-generated-by-nhibernate – Nathan

回答

0

我認爲這可能是一個簡單的錯字問題。

在你的例子中,在LinqPad中,你的where子句與加入的Customers進行比較。

但是,在您的LinqToNHibernate示例中,您的where子句與slastEntries進行比較,而不是加入的客戶c

因此,也許你的NHibernate的例子,你需要做的

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

即使重新排列仍然會產生相同的異常。看到NHibernate抱怨分組,我假設我需要在最後一條語句中添加分組子句,但我沒有看到它是正確的。 – kagundajm

+0

它並不總是必須是導致問題的最後一個語句,因爲LINQ使用延遲執行。 – Nathan

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();