0

テーブルの最後のエントリを取得し、それらを別のテーブルと結合して、不一致のあるエントリを生成したいと考えています。

次のエラーが表示されます

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

グループ化を可能にするためにステートメントを再配置しようとしましたが、正しくないようです。

エラーを防ぐ正しい構文はどれですか?

4

2 に答える 2

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();
于 2013-02-04T03:18:40.493 に答える
0

単純なタイプミスの問題かもしれないと思います。

LinqPadで機能する例では、where句がjoinedと比較されますCustomers

ただし、LinqToNHibernateの例では、where句は結合された顧客ではなくsfromと比較されます。lastEntriesc

したがって、おそらく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 ;
于 2013-02-03T21:14:25.130 に答える