我有以下场景,一个客户可以在多个银行拥有银行账户。这种关系在 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 中的每个键代表一个 Bank,Customer 在其中有一个帐户,字符串值是一个与此问题无关的简单状态。
我想做的是一个 NHibernate 查询,以检索在指定的银行 中拥有帐户的所有客户。我在 Bank 类中试过这个(因此 this 关键字指的是 Bank):
IList<Customer> customers = session.QueryOver<Customer>()
.Where(x => x.Banks.Keys.Contains(this))
.List();
即使我认为上面的查询编译没有错误,但当我尝试运行它时,我得到了以下异常:
System.Exception: Unrecognised method call: System.Collections.Generic.ICollection`1[[Finance.Bank, Finance, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]:Boolean Contains(Finance.Bank)
那么如何正确执行这种查询呢?谢谢!
附言:This SO question显示了如何为 ISet 集合执行此操作,并且 this SO question指出使用 ICriteria API 可能无法实现我正在尝试的操作。
最佳答案
经过更多研究后,我意识到 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_IDs。然后在第二个查询中使用生成的 Customer_IDs 列表来检索 Customers 对象。
PS:此解决方案适用于 SQL Server,但当我切换到 MySql 时,我不得不稍微更改它,因为它们代表 Guid structure以不同的方式。
关于c# - 如何使用 NHibernate 查询键值集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10972456/