【问题标题】:LINQ Fluent NHIBERNATE .Contains() does not work in QueryOver<> but works in Query<>LINQ Fluent NHIBERNATE .Contains() 在 QueryOver<> 中不起作用,但在 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 的方式有什么问题?

【问题讨论】:

标签: nhibernate fluent-nhibernate linq-to-nhibernate


【解决方案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&lt;SomeType&gt;,而是HashSet&lt;SomeType&gt;。显然,NH 真的希望它成为一个列表。所以,我这样做了,而且效果很好。

    var someEnumerableList = someEnumerable.ToList();
    _session.Query<SomeType>.Where(t => someEnumerableList.Contains(t)
    

    另外,FWIW,我的印象是 Query&lt;T&gt; 是新的首选方式,QueryOver&lt;T&gt; 是不太首选的方式,因为 Query&lt;T&gt; 返回 IQueryable,这意味着它应该更容易一些测试,理论上换掉 ORM。

    【讨论】:

    • 您对ToList() 的调用将执行查询,即它会导致服务器往返返回所有SomeType 类型的记录。我认为首选的选项是从满足Where() 子句的服务器中获取子集。似乎至少对于简单的情况这是可行的:session.Query&lt;Foo&gt;().Where(f =&gt; setOfIds.Contains(f.SomeId)) 并且其中SomeId 的类型为Guid。我们使用 NHibernate 5.1.0 版本。
    • 重要提示:NHibernate 并不是“真的希望它成为一个列表”。 HashSet 无法按预期工作的根本原因是 HashSet 依赖于 GetHashCode() 对其所有子对象保持不变的结果。至关重要的是,当您实现 NHibernate 时,您通常会在基本实体中覆盖 Equals()GetHashCode()... 结果是,当您保存实体并获得 ID 时,该实体的 GetHashCode() 值会发生变化,现在 HashSet 无法在其自身中找到它。 List 不依赖于GetHashCode(),所以它可以工作。
    【解决方案3】:

    像这样:

        query = query.WhereRestrictionOn(x => x.DescricaoDoProduto.Homogenize()).IsInsensitiveLike
    (filter.Description.Homogenize());
    

    【讨论】:

      猜你喜欢
      • 2023-03-31
      • 1970-01-01
      • 2017-10-31
      • 2021-01-29
      • 2011-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多