我有以下查询,并且在Nhibernate 3 LINQ中失败并出现“不受支持”的异常。它similar to this question,但这个问题是在一年前提出来的,所以我很肯定答案是过时的。
我的数据库表格是:
我的实体是:
以下是获得“不支持”异常的查询
Session.Query<VacationRequestDate>()
.Where(r => people
.Contains(r.VacationRequest.Person, new PersonComparer()))
.Fetch(r=>r.VacationRequest)
.ToList();
有没有更好的方法来编写Nhibernate支持的内容?
fyi。 。比较人员比较人.Id答案 0 :(得分:2)
nhibernate无法翻译您应该更改的new PersonComparer()
。
答案 1 :(得分:1)
NHibernate不理解PersonComparer
类型,因此无法将其用法转换为SQL。
您是否尝试使用不接受比较器的Contains
重载? NHibernate应该推断您正在比较实体实例并在SQL比较中正确使用ID(它还能使用什么?):
Session.Query<VacationRequestDate>()
.Where(r => people.Contains(r.VacationRequest.Person))
.Fetch(r => r.VacationRequest)
.ToList();
另外,请记住,在单个NHibernate会话中,始终为相同的ID返回相同的实体实例。这意味着如果从同一会话中检索到两个person1 == person1
实例,则Person
应始终为true。这也会带来关系,因此如果两个休假请求具有相同的人员ID,vacationRequest1.Person == vacationRequest2.Person
也将在同一会话中成立。
这意味着你可以完全摆脱PersonComparer
,除非你通过缓存混合来自多个会话的实体。
答案 2 :(得分:0)
对于初学者来说,它无法在你的数据库中执行代码。
这里有关于如何解决这个问题的建议
var peopleIds= people.Select(x=>x.Id);
Session.Query<VacationRequestDate>()
.Where(r => peopleIds.Contains(r.VacationRequest.PeopleId)).ToList()
.Where(x=>people.Contains(r.VacationRequest,new
PersonComparer()).Select(r=>r.VacationRequest).ToList()
如果您认为这不是您想要做的话,那么我建议您尝试使用Criteria查询或HQL,您可以从数据库中获得您想要的内容。
您也可以按如下方式使用比较器。我想让我的通用。 您也可以进行字符串比较,并在此处添加忽略大小写等逻辑。
public class ComparerByIntId<T> : IEqualityComparer<T>
where T : class, IIntegerIdentifiable
{
public bool Equals(T x, T y)
{
if (x == null && y == null)
return true;
if (x == null || y == null)
return false;
return x.Id == y.Id;
}
public int GetHashCode(T obj)
{
return base.GetHashCode();
}
}
现在,当您运行查询时,它将如下所示:
Session.Query<VacationRequestDate>()
.Where(r => people
.Contains(r.VacationRequest.Person, new ComparerByIntId<Person>()))
.Select(r=>r.VacationRequest)
.ToList();
希望有所帮助