My first experience with LINQ to NHibernate

Weeks ago we decided to upgrade to NHibernate 2.1.2
to be beneficiary of LINQ-to-NHibernate and other new features of last version of NHibernate. After introducing LINQ technology in .NET 3.0 many people were thinking the lack of a LINQ provider for NHibernate until when Ayende Rahien introduced the existence of LINQ-to-NHibernate.

My colleague Masoud and I started to replace a group of old NHibernate queries with LINQ-to-NHibernate queries. We progressed the task quickly and finished the entire task in few days. But very soon realized that writing LINQ-to-NHibernate queries is not as easy as we thought. Our queries were based on my knowledge of LINQ-to-Objects but many features working in LINQ-to-Objects was not working in LINQ-to-NHibernate. For example short circuit evaluation was not working. We tried to solve problems specially with help of StackOverflow. And here is some of encountered problems and their solution:

1. (TargetInvocationException): Exception has been thrown by the target of an invocation., (NullReferenceException): Object reference not set to an instance of an object., Occurs when a compare in LINQ throws an exception, this exception is wrapped in a TargetInvocationException exception and rethrowed. Like: l.Sender.Role.Contains(senderRoleSearch.Trim()) when senderRoleSearch == null

 2. Working with Enums is a bit strange. If you have a mapping like this:

then you will encounter some odd errors like:l.LetterType == LetterType.Internal results in “(QueryException): Type mismatch in NHibernate.Criterion.SimpleExpression: LetterType expected type System.Int32, actual type Faraconesh.EnterpriseAppUnits.OfficeAutomation.BusinessEntities.LetterType,. In this case you should remove type=”int” from the mapping. solution. For more information go here.

 3. When you have such a query:

var q=from l in session.Linq<Letter>

where crit == null ? true : l.Subject.Contains(crit.Trim())

select l;

You will probably encounter with “null object reference” because LINQ has not short-circuit evaluation. For more info go here and here.

4. Dynamic query:
While using nulls and nullables is not possible due to case 3 (above), You can use dynamic queries like this:

var q = from l in session.Linq()
select l;

if (serialNumberSearch != null)
q = q.Where(l => l.SerialNumber == serialNumberSearch.Trim());

5. Can not call methods: We were not able to find a solution.

 6. Subqueries does not work. Here is a our work-around.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *