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 类中尝试了这个(因此this关键字指的是银行):

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 question展示了如何为ISet集合执行此操作,并且这个 SO question指出我尝试使用 ICriteria API 可能无法实现。

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列表来检索客户对象。

PS:这个解决方案适用于SQL Server,但是当我切换到MySql时,我不得不稍微改变它,因为它们以不同的方式表示Guid 结构

于 2012-06-16T15:09:30.687 回答