How to translate a QueryOver to DetachedCriteria? - nhibernate

I do not wish to know why it's better to use QueryOver and that it's newer.
How can I translate the following QueyOver to a DetachedCriteria:
QueryOver<Category>().Where(x => x.Properties.Any(y => y.Locales.Any(l => l.Value.Name == "propName")));
I don't know if the "Any" extension method is recognized by nhibernate but you can understand what I'm trying to accomplish.

var subquery = DetachedCriteria.For<Category>()
.CreateCriteria("Properties")
.CreateCriteria("Locales")
.Add(Expression.Eq("Name", "propName"));

Related

Where clause using LIKE condition in MVC4 lambda

I want to show results where w.DrawDate contains (LIKE %year%) the year.
return View(db.Euro.Select(p => p).Where(w => w.DrawDate == year).ToList());
As seen in Like condition in MVC4 using lambda, i should use the Contains() method, but it isn't available.
So, how can i make w.DrawDate == year into w.DrawDate LIKE %year%?
You already have the answer:
View(db.Euro.Where(w => w.DrawDate.Contains(year)).ToList());
And you're probably just missing a namespace

Can I use SQL functions in NHibernate QueryOver?

I have been searching the internet and can't find an example on how to use the queryover of nhibernate 3.0
For example I would like to use the string functions on the where clause of the queryover
ex:
var item = Query.Where(x => x.Name.ToLower() == name.ToLower()).FirstOrDefault();
But this doesn't work, because nhibernate can't understand the ToLower, so how can extend the dialect in a way that this becomes possible?
session.QueryOver<Foo>()
.Where(Restrictions.Eq(
Projections.SqlFunction("lower", NHibernateUtil.String,
Projections.Property<Foo>(x => x.Name)),
name.ToLower()))
should get you SQL like where lower(Name) = #p0
I believe it works at least in the build I am using (version 3.0.0.4000)... below is my example...
var reasons = _session.Query<Reason>();
var myReason = (from r in reasons
where r.IsCritical
&& r.ReasonCode.ToUpper() == reasonCode.ToUpper()
select r).FirstOrDefault();
Give it a shot and let me know if it works for you...

NHibernate QueryOver order by first non-null value (coalescing)

What I'm trying to come up is something that's expressed like this:
var result = Session.QueryOver<Foo>().OrderBy(f => f.UpdatedAt ?? f.CreatedAt);
Sure enough, this doesn't work. Rough equivalent of this in T-SQL is
... order by coalesce(f.UpdatedAt, f.CreatedAt)
What's the kosher way to do "coalescing" in NHibernate QueryOver?
.OrderBy(Projections.SqlFunction("coalesce",
NHibernateUtil.DateTime,
Projections.Property<Foo>(x => x.UpdatedAt),
Projections.Property<Foo>(x => x.CreatedAt)))
Diego's answer is the way I came up with, but it seemed to be too verbose to me, so I asked a question, and got an excellent answer. Basically, you can register your own extensions and then just do
.OrderBy(f => f.UpdatedAt.IfNull(f.CreatedAt));
where IfNull is your new extension. I've even submitted an improvement proposal to NH Jira, but got no response yet.

Group by using linq with NHibernate 3.0

As far as I know group by has only been added in NHibernate 3.0, but even when using version 3, I can't get group by to work.
I have tried to do the following query:
Session.Query().GroupBy(gbftr
=> gbftr.Tag).OrderByDescending(obftr => obftr.Count()).Take(count).ToList();
But I receive the following error:
Antlr.Runtime.NoViableAltException'. [. OrderByDescending (. GroupBy (NHibernate.Linq.NhQueryable `1 [Forum.Core.ForumTagRelation] Quote ((gbftr,) => (gbftr.Tag)),), Quote ((obftr,) => (. Count (obftr,))),)]
Does anyone have an idea if I might be mistaken, and group by isn't implemented in NHibernate 3.0, or who knows what I might be doing wrong?
GroupBy does work, but it's the combination with other operators that is causing trouble.
For example, this works:
session.Query<Foo>().GroupBy(x => x.Tag).Select(x => x.Count()).ToList();
But if you try to use Skip/Take to page, it fails.
In short: some constructs are not supported yet; you can use HQL for those. I suggest you open an issue at http://jira.nhforge.org

Method 'Boolean Contains(System.String)' has no supported translation to SQL

"Method 'Boolean Contains(System.String)' has no supported translation to SQL."
query is IsQueryable but this stopped working:
foreach (string s in collection1)
{
if (s.Length > 0)
{
query = query.Where(m => m.collection2.Contains(s));
}
}
UPDATE: it works when i make query "ienumerable" instead of iqueryable. What would be the way to get same result using linq instead of iterating through loop?
Try this:
query = query.Where(m => m.collection2.ToList().Contains(s));
^^^^^^^^
Take a look at this answer from stackoverflow.
It looks like the resulting query would need access to something that the database
has no way of reaching, because the info is in memory.
Since m.collection2 is in the database, don't use Contains. Use Any
m.collection2.Any(x => x == s)
It looks like the error you are seeing is coming from the collection collection 2. Have you tried wrappering the m.collection2 in another function which returns true or false? Is this LINQ syntax?