LINQ Fluent NHIBERNATE .Contains() does not work in QueryOver<> but works in Query<>
Asked Answered
L

3

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?

Lynelllynelle answered 7/4, 2013 at 13:14 Comment(4)
I Think you need to read this first #5329065Quickly
Thanks for the link. However, how can I perform the same thing using .Contains() using QueryOver<>?Lynelllynelle
I like this solution better: #4739629Semiology
@JacobBrewer, that solutions does not work because it only checks with a single childId. Need an IN clause.Lynelllynelle
L
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()

Lynelllynelle answered 7/4, 2013 at 13:58 Comment(0)
W
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.

Woolcott answered 28/8, 2014 at 17:21 Comment(2)
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<Foo>().Where(f => setOfIds.Contains(f.SomeId)) and where SomeId is of type Guid. We use version 5.1.0 of NHibernate.Gallegos
IMPORTANT: It's not that NHibernate "really wants it to be a list." The underlying reason that HashSet<T> doesn't work as expected is that HashSet<T> 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<T> can't find it within itself anymore. List<T> doesn't rely on GetHashCode(), so it works.Maryland
E
-1

like this:

    query = query.WhereRestrictionOn(x => x.DescricaoDoProduto.Homogenize()).IsInsensitiveLike
(filter.Description.Homogenize());
Ednaedny answered 30/9, 2019 at 1:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.