Nhibernate 3.0 Complex queries - nhibernate

I need to perform queries that can be very complex, and I wanna make sure linq/queryOver can handle it.
what's the limitations and abilities I can't get with linq and can get with sql/hql ?

There isn't a list of limitations, other than the list of open bugs in Jira.
if you are performing complex queries, HQL is usually the best way to go.

However complex the query is you cna ultimately convert it toa QueryOver it might just get a little difficult and hard to read, but then you have a very strongly typed API.
Having said that you can always use HQL on your object model to achieve the same.
Session.CreateQuery("").List<>();
if that is difficult then there is always SQL to do the same.
Session.CreateSqlQuery("").ExecuteUpdate<>();
Session.CreateSqlQuery("").List<>();

Related

Is NHibernate 3.0 built-in Linq provider stable?

Can i depend on NHibernate 3.0 built-in Linq provider to perform complex queries contain aggregate functions such as Max and Min and contains string operations such as Contains, StartsWith, or EndsWith ??
The noticeable problems I found is:
.OfType() method is not implemented that can be a problem with inheritance hierarchies.
Left joins are not supported
Non-trivial group by operations do not work (even something as simple as sorting by group count).
Fetch() must be the last method in the query which can make paging with associated collections difficult.
However, it is definitely an improvement from the NHContrib provider.
The operations you listed are supported just fine in the usual scenarios.
There has been much debate on the nhusers list as there are quite a few issues still outstanding.
I would look on the nhusers group and
read some of the posts and make your
own mind up. See here for posts.
Personally I have found that queryover does all that I need so I for one would wait until the Linq provider becomes more stable over time.
I would recommned in joining the nhusers group to get a better feel.
The LINQ provider is far more stable and advanced than the one written by Ayende. (not dising what he wrote it was because of what he wrote that i picked up NH again)
I think the only issue I've come across with NH Query is composite types. You can do them in EF/L2S, and NH3 seems to generate the correct sql but fails to get to executing it.
Personally I like QueryOver, it reads better to me.

In what situations should I use Entity SQL?

I was wondering whether there are situation that's more advisable to use ESQL?
Generally, I find ESQL frustrating (specially with all the special cases where you need to fully qualify an entity type) & probably anything done using ESQL can be done through SQL or LINQ.
But I was wondering of situations where ESQL is a better fit for a solution or would have a competitive edge over using SQL or LINQ (either easier/faster to code, or better performance, etc.)
So, what's the compromise here? When is it better to use each one of the three approaches in querying over EF4?
I find that ESQL to be good for edge cases, for example:
Where it's just really hard to express something in LINQ.
For building very dynamic searches.
If you want to use a database specific function that is exposed by the provider you are using.
Also, if you know Entity SQL, you will be able to express QueryViews and Model-Defined Queries.
I came across these pretty similar questions (which didn't show up when I typed mine, earlier) on stack over flow, I guess they have deeper discussions (though T-SQL is not mentioned a lot, but it's kinda pretty obvious though):
Linq to Entities vs ESQL - Stack
Overflow
Entity framework entity sql vs linq
to entities
Note that the two questions are a bit "old" so you might validate some of data based on your current understanding of EF4
Just as what julie mentioned. Esql is required to write model defined functions which in return can be used through LINQ to Entities Queries.
Most cased you'll be using LINQ to Entities. One another case where you can't use LINQ TO Entities us when you want to build queries with store functions, either buit in or UDF. In this case esql is your only way in EF1 but in EF4 you can use its features to expose those functions to be used in LINQ.
About performance, esql is performing better. but you might prefer productivity using Linq over performance gain using esql.

entity framework entity sql vs linq to entities

what's the purpose of entity sql, i mean if you have linq to entities why would you need to write queries in string, are there any performance reasons or something ?
LINQ to Entities does not allow you access to every feature of your database. Being able to "reach into" the database is sometimes necessary for advanced queries, either to pull them off in the first place or to improve the sometimes horrible choices that the LINQ to Entities system will make about your query.
That said, I believe that LINQ to Entities should be the first tool reached for. If the performance becomes a problem, or you have something more complex I would then encapsulate that problem piece in a stored procedure and call that. There is no reason for strings being used as the basis of queries these days.
ESQL does allow you to choose a collation on a where clause, something which isn't supported in LINQ-to-Anything. This can be genuinely useful. ESQL also allows you to specify the precise type you want returned when types inherit from each other (as opposed to LINQ's OfType, which returns instances of a certain type and any subtype). Beyond that, I can't think of a great reason to use it. It's occasionally nice to be able to build queries in strings, but DynamicQuery/Dynamic LINQ is generally good enough in the very rare cases where this is necessary.
I think (perhaps cynically) that the "real" purpose of ESQL is "it predates LINQ."
Regarding Godeke's point of fixing non-optimal queries, I have yet to see one I couldn't fix by changing the LINQ expression. Both ESQL and L2E end up as CCTs, so the SQL generation pipeline is the same.

Is it a good idea to learn LINQ first, then SQL?

I know that in most cases it`s more useful to learn more complicated technology/language and then easy one than vice versa.
But, actually, time to do university tasks is limited. If I first learn LINQ, then go for SQL, would it be hard for me to use and learn sql?
EDIT
The task I need to do is to work with database and get some data from it, so the question is almost about LINQ to SQL.
It is a bad idea.
And if today's universities teach you LINQ instead of giving you foundation to build your knowledge upon, I can only feel sorry and pity for their students.
Time is always limited. Don't waste it on things that are subject to constant change.
SQL will be there tomorrow, LINQ.... well who knows.
SQL is applicable anywhere, LINQ only in .NET world.
Either LINQ or something else, it will be easy to "learn" it afterwards. When you have the knowledge of SQL, it will just me a matter of hours/days/weeks, hardly longer.
Well, the 2 things are very different. LINQ (in the pure sense) isn't actually related to databases at all - it can be used quite happily just with in memory objects, or against web services, etc.
If you are mainly interested in writing better .NET code, then learn LINQ - but learn it properly - perhaps pick up C# in Depth, for example - which covers it very well in the last few chapters.
If you want to know about databases, then sure: learn SQL (such as TSQL) - but understand the differences. Databases are good if you need to write enterprise software, but not necessarily if you just want to do simple tasks.
edit re edit to the question
If you are just getting simple data in and out of the database, then you probably don't need to know much about SQL. Just use LINQ-to-SQL (or whatever tool), and let the ORM tooling worry about it.
Learn SQL first, then LINQ.
That way you'll understand how LINQ-to-SQL is working behind the scenes, but you'll also know enough to be able to cope when LINQ can't do what you need.
SQL is a standard, learn the standard.
More precisely :
learn database theory
learn CODD algebra
then pick up a "common database", do some tutorials on it, ...
I personnaly really like PostgreSQL tutorial
I submit that you cannot effectively use LINQ unless you have SQL knowledge. If you don't understand, at a minimum, the following, you cannot effectively query a database in any fashion:
select
insert
delete
update
joins
group by
boolean algebra
relational theory
set theory
Learning SQL will give you the concepts you need even if you use LINQ later.
Sql. However you could play with linq pad for a while - it is a freeware and realize that LINQ is a nice hybrid between SQL and C#

Best practices for querying with NHibernate

I've come back to using NHibernate after using other technologies (CSLA and Subsonic) for a couple of years, and I'm finding the querying a bit frustrating, especially when compared to Subsonic. I was wondering what other approaches people are using?
The Hibernate Query Language doesn't feel right to me, seems too much like writing SQL, which to my mind is one of the reason to use an ORM tools so I don't have to, furthermore it's all in XML, which means it's poor for refactoring, and errors will only be discovered at runtime?
Criteria Queries, don't seem fluid enough.
I've read that Ayende's NHibernate Query Generator, is a useful tool, is this what people are using? What else is out there?
EDIT: Worth a read
http://www.ayende.com/Blog/archive/2007/03/17/Implementing-Linq-for-NHibernate-A-How-To-Guide--Part.aspx
The thing with LINQ for NHibernate is still in beta; I'm looking forward to NHibernate 2.1, where they say it will finally make the cut.
I made a presentation on LINQ for NHibernate around a month ago, you might find it useful. I blogged about it here, including slides and code:
LINQ for NHibernate: O/R Mapping in Visual Studio 2008 Slides and Code
To rid yourself of the XML, try Fluent NHibernate
Linq2NH isn't fully baked yet. The core team is working on a different implementation than the one in NH Contrib. It works fine for simple queries though. Use sparingly if at all for best results.
As for how to query (hql vs. Criteria vs. Linq2NH), expose intention-revealing methods (GetProductsForOrder(Order order), GetCustomersThatPurchasedProduct(Product product), etc) on your repository interface and implement them in the best way. Simple queries may be easier with hql, while using the specification pattern you may find the Criteria API to be a better fit. That stuff just stays encapsulated in your repository, and if your tests pass it doesn't much matter how you implement.
I've found that the Criteria API is cumbersome and limiting but flexible. HQL is more my style (and it's better than SQL - it's object based, not schema based) and seems to work better for me for simple GetX methods..
I use Linq for NHibernate by default. When I hit bugs or limitations, I switch to HQL.
It's a clean approach if you keep all your queries together in a data access class, such as a Repository.
public class CustomerRepostitory()
{
//LINQ for NHibernate
public Customer[] FindCustomerByEmail(string email)
{
return (from c in _session.Linq<Customer>() where c.Email == email).FirstOrDefault();
}
//HQL
public Customer[] FindBestBuyers()
{
var q = _session.CreateQuery("...insert complex HQL here...");
return q.List<Customer>();
}
}
You asked about refactoring. LINQ is obviously taken care of by the IDE, so for any remaining HQL, it's fairly easy to scan these repository classes and change HQL by hand.
Putting HQL in XML files is a good practice, maybe see if the ReSharper NHIbernate plugin can handle the query refactoring by now?
A big improvement when writing or refactoring queries (HQL or LINQ) is to put finder methods under unit test. This way you can quickly tweak the HQL/LINQ until you get a green bar. The compile/test/feedback loop is very fast, especially if you use an in-memory database for testing.
Also, if you forget to edit the HQL after refactoring, the unit tests should let you know about your broken HQL very quickly.
An alternative to LINQ-to-NHibernate and Ayende's NHQG is to generate NHibernate Expressions/Restrictions from C#3 Expressions. This way you get a more strongly-typed Criteria API.
See:
http://bugsquash.blogspot.com/2008/03/strongly-typed-nhibernate-criteria-with.html
http://www.kowitz.net/archive/2008/08/17/what-would-nhibernate-icriteria-look-like-in-.net-3.5.aspx
http://nhibernate.info/blog/2009/01/07/typesafe-icriteria-using-lambda-expressions.html
scrap nHibernate and go back to Subsonic if you can. In my opinion, Subsonic is a far more fluent and testable ORM/DAL. I absolutely hate HQL what's the point of a weakly typed query in an ORM? And why would I use Linq/nH/SQL when I can just use Linq to SQL and cut out a layer?
nHibernate was a good ORM when Subsonic wasn't around, but now, it's just plain awful to work with in comparison. It easily takes me 2 times longer to do stuff with nHibernate vs Subsonic. Testing is a pain since nHibernate is runtime, so now I need to employ a few QA engineers to "click" around the site instead of getting a compile time error.