23

Using FNH, i am trying to retrieve categories, using the following:

_session.QueryOver<Data.Model.Category>()
                                     .Where(c => tourCreateRequest.Categories.Contains(c.CategoryId))
                                     .List()
                                     .Select(_categoryMapper.CreateCategory)
                                     .ToList();

But I get an error at the .Contains() method :

Unrecognised method call: System.Collections.Generic.ICollection`1[[System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]:Boolean Contains(Int64)

Why am I getting that error, what is wrong?

I went through some posts, and then changed my query to (below), and this works with Query<>.

_session.Query<Data.Model.Category>()
                                     .Where(c => tourCreateRequest.Categories.Contains(c.CategoryId))
                                     .ToList()
                                     .Select(_categoryMapper.CreateCategory)
                                     .ToList();

I thought QueryOver<> is the latest and greatest and should be used instead of Query<>.

What is the issue with the way I am using QueryOver<> as shown above?

jaxxbo
  • 7,314
  • 4
  • 35
  • 48
  • I Think you need to read this first http://stackoverflow.com/questions/5328565/nhibernate3-query-vs-queryover – frictionlesspulley Apr 07 '13 at 13:27
  • Thanks for the link. However, how can I perform the same thing using .Contains() using QueryOver<>? – jaxxbo Apr 07 '13 at 13:36
  • I like this solution better: http://stackoverflow.com/questions/4739129/linq-to-nhibernate-where-collection-contains-object-with-id – Jacob Brewer Apr 29 '14 at 21:34
  • @JacobBrewer, that solutions does not work because it only checks with a single childId. Need an IN clause. – jaxxbo May 02 '14 at 19:17

3 Answers3

33

I found the answer. Thanks to the post at: NHibernate using QueryOver with WHERE IN

var categories = _session.QueryOver<Data.Model.Category>()
                                     .WhereRestrictionOn(c => c.CategoryId).IsIn(ArrayofCategoryIds)
                                     .List()
                                     .Select(_categoryMapper.CreateCategory)
                                     .ToList();

I had to use the WhereRestrictionOn()

Community
  • 1
  • 1
jaxxbo
  • 7,314
  • 4
  • 35
  • 48
8

This is tangentially related issue and this seemed like the best place to put it.

_session.Query<SomeType>.Where(t => someEnumerable.Contains(t))

was not working.

In my case someEnumerable was NOT a List<SomeType>, but rather a HashSet<SomeType>. Apparently, NH really wants it to be a list. So, I did this instead and it worked.

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

Also, FWIW, I was under the impression that Query<T> was the new preferred way to go and that QueryOver<T> was the less preferred way, because Query<T> returns IQueryable, meaning that it should be a little easier to test, and theoretically swap out ORMs.

viggity
  • 15,039
  • 7
  • 88
  • 96
  • Your call to `ToList()` executes the query, ie it causes a server round trip returning all records of type `SomeType`. I think the preferred option would be to just get the subset from the server that satisfies the `Where()` clause. It seems that at least for simple cases this works: `session.Query().Where(f => setOfIds.Contains(f.SomeId))` and where `SomeId` is of type `Guid`. We use version 5.1.0 of NHibernate. – Manfred Apr 23 '18 at 01:36
  • IMPORTANT: It's not that NHibernate "really wants it to be a list." The underlying reason that HashSet doesn't work as expected is that HashSet relies on the result of `GetHashCode()` remaining constant for all its child objects. And crucially, when you implement NHibernate you usually override `Equals()` and `GetHashCode()` in a base entity... The result is that when you save your entity and it gets an ID, the value of `GetHashCode()` for that entity changes, and now HashSet can't find it within itself anymore. List doesn't rely on `GetHashCode()`, so it works. – S'pht'Kr Aug 03 '20 at 10:08
-1

like this:

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