3

次のシナリオがあります。複数の銀行に銀行口座を持つことができる顧客です。この関係は、CustomerクラスのIDictionaryとして記述されます(mapタグを使用してマップされます)。

public class Customer
{
    public virtual IDictionary<Bank, string> Banks
    {
        get { return _Banks; }
        set { _Banks = value; }
    }
    private IDictionary<Bank, string> _Banks = new Dictionary<Bank, string>();
}

IDictionaryの各キーは、顧客がアカウントを持っている銀行を表し、文字列値はこの質問には関係のない単純なステータスです。

私がやりたいのは、指定された銀行に口座を持つすべての顧客を取得するためのNHibernateクエリです。私はこれをBankクラス内で試しました(したがって、このキーワードはBankを参照しています):

IList<Customer> customers = session.QueryOver<Customer>()
                                   .Where(x => x.Banks.Keys.Contains(this))
                                   .List();

そして、上記のクエリを実行しようとするとエラーなしでコンパイルされたとしても、次の例外が発生します。

System.Exception:認識されないメソッド呼び出し:System.Collections.Generic.ICollection`1 [[Finance.Bank、Finance、Version = 1.0.0.0、Culture = neutral、PublicKeyToken = null]]:Boolean contains(Finance.Bank)

では、どうすればこの種のクエリを正しく実行できますか?ありがとう!

PS:このSOの質問は、 ISetコレクションに対してそれを行う方法を示しています。このSOの質問は、ICriteriaAPIを使用して私が試みていることは不可能である可能性があることを示しています。

4

1 に答える 1

1

さらに調査した結果、 Containsメソッドに含まれるロジックを一般的な方法でSQLに簡単に変換できない可能性があることに気付きました。そのため、例外が発生していました。

興味のある人のために、私は次の回避策を思いついた:

IList<Guid> customerIds = session.CreateSQLQuery(
            "SELECT Customer_ID FROM Banks WHERE Bank_ID = '" + this.ID + "'")
            .List<Guid>();

Guid[] array = new Guid[customerIds.Count];
customerIds.CopyTo(array, 0);

IList<Customer> customers = session.QueryOver<Customer>()
                .Where(Restrictions.In("ID", array)).List();

まず、指定されたBank_IDの関連付けテーブルからすべてのCustomer_IDをフェッチします。次に、結果のCustomer_IDのリストを、 Customersオブジェクトを取得するための2番目のクエリで使用します。

PS:このソリューションはSQL Serverで機能しましたが、 MySqlに切り替えたとき、 Guid構造をさまざまな方法で表すため、少し変更する必要がありました。

于 2012-06-16T15:09:30.687 に答える