Hello. I have a problem with the creation of a Hibernate Criteria object. I'm new to Hibernate.
Can someone help me with the creation of a complex Criteria object and explain how this is done? Here is the sample SQL select statement to emulate:
select * from Company join Employees on Company.IDCompany = Employees.IDCompany;
If you user NH3 you can use QueryOver instead of ICriteria, as for me QueryOver expressions are better than ICriteria strings.
Session.QueryOver<Company>()
.JoinQueryOver(company => company.Employees)
.Where(...) // some restrictions
.List<Company>();
http://nhforge.org/blogs/nhibernate/archive/2009/12/17/queryover-in-nh-3-0.aspx
Related
I am new to hibernate criteria API. I have written the below query in SQL. How to write it in the Hibernate criteria?
select * from Employee ju, Address ua where
ua.loginname=ju.loginname
and ua.countryname='USA'
and ju.siteprimcontact=1;
Here is a tutorial on the JPA Criteria API that you can use to learn how to write such queries: https://docs.oracle.com/javaee/6/tutorial/doc/gjivm.html
any one know what kind of query is this??
var r = dc.user_details.Where(a => a.username.Equals(u.username) && a.passkey.Equals(u.passkey)).FirstOrDefault();
It is LINQ query. (The Enumerable methods are part of system.linq namespace)
The method "where" is part of "Enumerable Methods".
https://msdn.microsoft.com/en-us/library/system.linq.enumerable_methods(v=vs.110).aspx
Inside "Where" the predicate is a lamda expression. (This is a C# programming concept. Not part of LINQ)
https://msdn.microsoft.com/en-us/library/bb397687.aspx
Again the "FirstOrDefault" is a "Enumerable method", You can find it in the first link.
These are an extension methods that achieves the same as LINQ. It is another way for writing LINQ queries.
This is a linq query which checks the username and passkey and gives the result weather the user name and passkey exist in the table or not.
Ayende describes a really great way to get page count, and a specific page of data in a single query here:
http://ayende.com/blog/2334/paged-data-count-with-nhibernate-the-really-easy-way
His method looks like:
IList list = session.CreateQuery("select b, rowcount() from Blog b")
.SetFirstResult(5)
.SetMaxResults(10)
.List();
The only problem is this example is in HQL, and I need to do the same thing in an ICriteria query. To achieve the equivalent with ICriteria, I need to do something like:
IList list = session.CreateCriteria<Blog>()
.SetFirstResult(5)
.SetMaxResults(10)
.SetProjection(Projections.RootEntity(), Projections.SqlFunction("rowcount", NHibernateUtil.Int64))
.List();
The problem is there is no such thing as Projections.RootEntity(). Is there any way to select the root entity as one of the projections in a projection list?
Yes, I know I could just use CriteriaTransform.TransformToRowCount() but that would require executing the query twice - once for the results and once for the row count. Using Futures may help a little by reducing it to one round-trip, but it's still executing the query twice on the SQL Server. For intensive queries this is unacceptable. I want to avoid the overhead, and return the row count and the results in the same query.
The basic question is: using ICriteria, is there any way to select the root entity AND some other projection at the same time?
EDIT: some related links:
https://nhibernate.jira.com/browse/NH-1372?jql=text%20~%20%22entity%20projection%22
https://nhibernate.jira.com/browse/NH-928
I implemented a RootEntityProjection. You can try the code, which you can find at: http://weblogs.asp.net/ricardoperes/archive/2014/03/06/custom-nhibernate-criteria-projections.aspx.
Let me know if it helped.
NHibernate.Linq returns IQueryable giving me late evaluation. Can this also be done with QueryOver?
Update:
I will use it to define lots of queries where only a subset would be used. Therefor Future is not the solution, which would execute them all.
I like the IQueryable (IEnumerable) return type from NHibernate.Linq, that will never execute the query if never used.
Firstly, even QueryOver is just a set of definitions to be later converted to the SQL statement. So until you are working with a reference to a
IQueryOver<Entity, Entity> ab = session.QueryOver<Entity>();
and not calling List<Entity>() ... the execution is deferred. That's also how you can use the Detached queries 16.1. Structure of a Query
QueryOver<Cat> query = QueryOver.Of<Cat>()
.Where(c => c.Name == "Paddy");
Another powerful feature is Future. This represents a very easy way how to put few queries on the stack, and only when first of them is required... all are executed and passed to DB Server as a batch. Read here more: NHibernate Futures
They essentially function as a way to defer query execution to a later
date, at which point NHibernate will have more information about what
the application is supposed to do, and optimize for it accordingly
The biggest difference is that it cannot be returned as IQueryable when using QueryOver
EDIT: Extend on a question update
While IQueryable<TEntiy> could be returned only from a session.Query<TEntity>() and not when using QueryOver, ICriteria, HQL ... the same behavior could not be reached when using QueryOver.
Using nHibernate QueryOver, if I want to enforce a projection for performance, are "Select" and "Where" the same thing? In other words, will ..
var member = session.QueryOver<Member>()
.Select( projections => projections.Email == model.Email )
.Take(1).SingleOrDefault();
Run the same as
var member = session.QueryOver<Member>()
.Where( context => context.Email == model.Email )
.Take(1).SingleOrDefault();
Or is there a difference in the two?
Select projects (you could also say maps); Where filters. This is the same as SQL and all LINQ providers (and QueryOver is also sort of a LINQ provider). It seems that in this case you want to filter, not project, so you need Where
No offense intended, but I think the best way to answer a question like the one you asked is to try it. Sometimes things become clearer when you can see the output.
That said, when you use Select, you're telling NHibernate how to project your data. This determines the final makeup of the data resulting from the query. There's a little bit more to this, but that's the general idea. You use Where when you want to specify the criteria that the data that you are querying should satisfy.