LINQ Fluent NHIBERNATE .Contains() 在 QueryOver<> 中不起作用,但在 Query<> 中起作用
Posted
技术标签:
【中文标题】LINQ Fluent NHIBERNATE .Contains() 在 QueryOver<> 中不起作用,但在 Query<> 中起作用【英文标题】:LINQ Fluent NHIBERNATE .Contains() does not work in QueryOver<> but works in Query<> 【发布时间】:2013-03-29 13:43:01 【问题描述】:使用 FNH,我正在尝试使用以下方法检索类别:
_session.QueryOver<Data.Model.Category>()
.Where(c => tourCreateRequest.Categories.Contains(c.CategoryId))
.List()
.Select(_categoryMapper.CreateCategory)
.ToList();
但我在 .Contains() 方法中遇到错误:
无法识别的方法调用: System.Collections.Generic.ICollection`1[[System.Int64,mscorlib, 版本=4.0.0.0,文化=中性, PublicKeyToken=b77a5c561934e089]]:布尔包含(Int64)
为什么我会收到这个错误,有什么问题?
我浏览了一些帖子,然后将我的查询更改为(如下),这适用于 Query。
_session.Query<Data.Model.Category>()
.Where(c => tourCreateRequest.Categories.Contains(c.CategoryId))
.ToList()
.Select(_categoryMapper.CreateCategory)
.ToList();
我认为 QueryOver 是最新最好的,应该用来代替 Query。
如上所示,我使用 QueryOver 的方式有什么问题?
【问题讨论】:
我认为您需要先阅读此内容***.com/questions/5328565/… 感谢您的链接。但是,如何使用 .Contains() 使用 QueryOver 执行相同的操作? 我更喜欢这个解决方案:***.com/questions/4739129/… @JacobBrewer,该解决方案不起作用,因为它只检查单个 childId。需要一个 IN 子句。 【参考方案1】:我找到了答案。感谢发帖:NHibernate using QueryOver with WHERE IN
var categories = _session.QueryOver<Data.Model.Category>()
.WhereRestrictionOn(c => c.CategoryId).IsIn(ArrayofCategoryIds)
.List()
.Select(_categoryMapper.CreateCategory)
.ToList();
我不得不使用 WhereRestrictionOn()
【讨论】:
【参考方案2】:这是一个切线相关的问题,这似乎是放置它的最佳位置。
_session.Query<SomeType>.Where(t => someEnumerable.Contains(t))
没有工作。
就我而言,someEnumerable
不是List<SomeType>
,而是HashSet<SomeType>
。显然,NH 真的希望它成为一个列表。所以,我这样做了,而且效果很好。
var someEnumerableList = someEnumerable.ToList();
_session.Query<SomeType>.Where(t => someEnumerableList.Contains(t)
另外,FWIW,我的印象是 Query<T>
是新的首选方式,QueryOver<T>
是不太首选的方式,因为 Query<T>
返回 IQueryable,这意味着它应该更容易一些测试,理论上换掉 ORM。
【讨论】:
您对ToList()
的调用将执行查询,即它会导致服务器往返返回所有SomeType
类型的记录。我认为首选的选项是从满足Where()
子句的服务器中获取子集。似乎至少对于简单的情况这是可行的:session.Query<Foo>().Where(f => setOfIds.Contains(f.SomeId))
并且其中SomeId
的类型为Guid
。我们使用 NHibernate 5.1.0 版本。
重要提示:NHibernate 并不是“真的希望它成为一个列表”。 HashSetGetHashCode()
对其所有子对象保持不变的结果。至关重要的是,当您实现 NHibernate 时,您通常会在基本实体中覆盖 Equals()
和 GetHashCode()
... 结果是,当您保存实体并获得 ID 时,该实体的 GetHashCode()
值会发生变化,现在 HashSetGetHashCode()
,所以它可以工作。像这样:
query = query.WhereRestrictionOn(x => x.DescricaoDoProduto.Homogenize()).IsInsensitiveLike
(filter.Description.Homogenize());
【讨论】:
以上是关于LINQ Fluent NHIBERNATE .Contains() 在 QueryOver<> 中不起作用,但在 Query<> 中起作用的主要内容,如果未能解决你的问题,请参考以下文章
从 QueryOver(或者 Fluent NHibernate)中获取魔法字符串?
使用 Fluent NHibernate 有条件地将两列映射到一个字段
NHibernate 2 + Fluent Nhibernate 中等信任
NHibernate + Fluent NHibernate 异常