Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么“nhibernate”不支持这种“存在于列表中”语法?_C#_Linq_Nhibernate_Fluent Nhibernate - Fatal编程技术网

C# 为什么“nhibernate”不支持这种“存在于列表中”语法?

C# 为什么“nhibernate”不支持这种“存在于列表中”语法?,c#,linq,nhibernate,fluent-nhibernate,C#,Linq,Nhibernate,Fluent Nhibernate,我有以下查询,它在Nhibernate 3 LINQ中失败,有一个不受支持的异常。但是这个问题是一年前提出来的,所以我肯定答案已经过时了 我的数据库表是: 休假请求id,personId VacationRequestDate id,vacationRequestId 个人id、名字、姓氏 我的实体是: 休假请求人 休假请求日期休假请求,日期 以下是获取不受支持的异常的查询 Session.Query<VacationRequestDate>() .Where(r =>

我有以下查询,它在Nhibernate 3 LINQ中失败,有一个不受支持的异常。但是这个问题是一年前提出来的,所以我肯定答案已经过时了

我的数据库表是:

休假请求id,personId VacationRequestDate id,vacationRequestId 个人id、名字、姓氏 我的实体是:

休假请求人 休假请求日期休假请求,日期 以下是获取不受支持的异常的查询

 Session.Query<VacationRequestDate>()
   .Where(r => people
     .Contains(r.VacationRequest.Person, new PersonComparer()))
   .Fetch(r=>r.VacationRequest)
   .ToList();
有没有一种更好的方法可以在Nhibernate中得到支持


仅供参考。PersonComparer刚刚比较了person.Id。nhibernate无法翻译您的新PersonComparer。您应该更改它。

nhibernate不了解PersonComparer类型,因此无法将其用法转换为SQL

您是否尝试过使用不接受比较器的Contains重载?NHibernate应该推断您正在比较实体实例,并在SQL比较中正确使用ID它还可以使用什么

Session.Query<VacationRequestDate>()
    .Where(r => people.Contains(r.VacationRequest.Person))
    .Fetch(r => r.VacationRequest)
    .ToList();
另外,请记住,在单个NHibernate会话中,始终为相同ID返回相同的实体实例。这意味着,如果从同一会话检索到两个Person实例,则person1==person1应始终为true。这也会传递关系,因此vacationRequest1.Person==vacationRequest2.Person在同一会话中也将为true,如果两个假期请求具有相同的Person ID


这意味着您可能完全可以摆脱PersonComparer,除非您通过缓存从多个会话中混合实体。

对于初学者,它无法针对数据库中的实体执行代码

下面是我对如何进行这项工作的建议

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,您可以从db中得到您想要的

您还可以按如下方式使用比较器。我喜欢把我的变成普通的。 您也可以进行字符串比较,并在此处添加忽略大小写等逻辑

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();

希望这对你有所帮助,如果你在调试模式下看到表达式树,你可以看到它不能做到这一点,但我认为如果你覆盖你的人的平等成员,这可以小心地完成。[但如果您以前为了另一个目的而覆盖它,我建议使用hql]其中r=>PeopleId.Containsr.VacationRequest.PeopleId.ToList不是一个好建议,加载所有数据可能会导致崩溃,也很慢。它加载所有数据是什么?我们是21世纪的人。。你说它会崩溃是什么意思。假设每个人的数据都有1024字节大,那么返回的1024条记录的总空间是1024*1024=1mb内存,我当然认为这是可以管理的,除非我们突然想到1mb的内存限制。