NHDay Introduction to LINQ2NH


Published on

Slide of the LINQ2NH session of NHibernate Day 2010

Published in: Technology
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

NHDay Introduction to LINQ2NH

  1. 1. LINQ2NH<br />Ricci Gian Maria<br />Giorgetti Alessandro<br />
  2. 2. Nhibernate permits you to query database with different techniques<br />NHibernate support for Query<br />HQL<br />ICRITERIA<br />SQL<br />NHIBERNATE<br />
  3. 3. The LINQ query expressed by code gets translated into an “Expression Tree”<br />An Expression Tree is a representation of the query with a tree like this one<br />What is needed to build a LINQ provider<br /> 3 + (5 + 9) * 2<br />
  4. 4. If an arithmetic expression is simple to visualize as a tree a LINQ query could be more complex.<br />Luckily enough, we do not need to know this to use LINQ2NH, but is useful to understand the process<br />Expression Tree in real world<br />
  5. 5. We already have a LINQ2NH provider, is it not good?<br />We have LINQ2NH in 2.1.. So? <br />LINQ2NH<br />HQL<br />ICRITERIA<br />SQL<br />NHIBERNATE<br />
  6. 6. 2.1 LINQ provider is limited by features offered by ICriteria<br />The query gets translated from ExpressionTree to ICriteria then from ICriteria to the real query<br />ICriteria misses some features like Having clause<br />It is difficult to create complex query with ICriteria so it is difficult to support full LINQ syntax<br />Current situation<br />
  7. 7. First of all there was a rewrite of the HQL parser using an AST (Abstract Syntax Tree) based on ANTLR<br />Steve Strong started from the Java ANTLR parser and converted for C#<br />The resulting HQL engine now has four steps, the hard work is between 2nd and 3rd steps<br />A new idea – use HQL<br />
  8. 8. Why rewrite HQL parser is needed for LINQ<br />The big idea is to create a provider that translate an Expression Tree to the same Parse Tree of HQL<br />STRING(HQL)<br />LINQ<br />The complex part, is translating the Parse tree<br />Translation of parse tree is the point where mappings are consulted to generate the SQL tree<br />Reusing the same code for HQL and LINQ is the key for success and performance<br />PARSE TREE<br />ICRITERIA<br />SQL<br />NHIBERNATE<br />
  9. 9. Is LINQ2NH mature enough?<br />Actually the provider supports many features, but since parsing an Expression Tree is not so simple we still have something unsupported<br />We will see this in detail in the second part, you should simple be aware that not full LINQ syntax is supported<br />
  10. 10. Whylinq 2 NH<br />If we already have HQL, ICriteria and SQL, we really need LINQ?<br />
  11. 11. LINQ is strongly typed, so you have full intellisense power and compile time checking<br />Refactoring capabilities, if you rename a property of a mapped class, you automatically have your LINQ queries updated<br />LINQ is standard in .NET, maybe you already know it, and you can use to query XML, object in memory, LDAP tree, Entity Framework  and so on.<br />Differencebetween HQL and LINQ<br />
  12. 12. Deferred execution – a key concept of LINQ<br />Some of the LINQ operator are called: “deferred” operator<br />A deferred operator is evaluated only during the iteration of the content, or if you call a “not deferred” operator (like ToList() )<br />
  13. 13. Deferred execution – even in LINQ2NH<br />The very same happens for LINQ2NH queries.<br />Nothing get executed here, you are only defining a query like you do with ICriteria<br />Since Count is a “non deferred” operator, a query to the database is issued.<br />
  14. 14. LINQ query is an expression tree that can be manipulated by code <br />Like ICriteria is simple to add and remove condition, projections to an existing query.<br />You can pass a LINQ query between layers, each layer can manipulate the query in a very simple way.<br />Differencebetween HQL and LINQ<br />
  15. 15. Very easy projection<br />You can have one layer that manage the where part and another one that use projection<br />You can project into Dto (Data Transfer Object) with great easy, respect HQL<br />You can leverage Anonymous Type instead of DTO.<br />Difference between HQL and LINQ<br />
  16. 16. You can build on the fly complex anonymous DTO, with calculation in it and let the provider do the work<br />LINQ is expressive<br />Since you want to use the year part of the BirthDate property, the provider is using datepart SQL function<br />Provider is smart, and select only what is needed and not unnecessary properties<br />
  17. 17. Linq to Nh – Part 2<br />
  18. 18. A thing you need to be aware of…<br />Some things that actually ‘do not work’<br />How to extend the provider to overcome issues and add features.<br />Part 2 - Agenda<br />
  19. 19. Nhibernate best practice: use explicit Transations!<br />Deferred execution might cause troubles when coupled with Transaction Management policies.<br />It’s very easy to execute code outside the scope of a transaction, and you will hardly spot it at first.<br />If your repository/dao or whateever data access strategy you have, exposes IQueriable<T> interfaces you need to be careful and call the functions that actually ‘trigger’ the Linq query evaluation inside the scope of your transation (i.e.: GetEnumerator(), Count(), ToList(), Single(), etc…).<br />A Thing to be Aware of…Linq2Nh and Transactions<br />
  20. 20. Some Functions/Operators not supported – for example: Equals() is supported only for strings at the moment, for all other types you can use the ==operator.<br />Problems when using Ilists<T> while trying to create expressions that use ‘contains’ to realize ‘Select..from…where..in’ queries. The parser goes crazy and try to compare an IList<T> to T entities.<br />Custom IUserType(s) not supported yet. (It’s a bug and should be corrected soon..remember it’s an alpha version).<br />Problems with some Joins and Nested Queries, you need to rework your code if you want to use Linq to perform these kind of queries.<br />During everyday usage of the provider you can encounter the following problems:<br />Some things that actually ‘do not work’<br />
  21. 21. Fix some of the holes in the provider – the missing equals for example.<br />Add new features and functionalities.<br />Extending the provider is very easy and it allows you to:<br />Extending Linq To NHibernate<br />
  22. 22. Given your Linq Query a parser examines it.<br />Each segment of the expression that forms the query is translated from a Linq Expression to an Hql Expression (The old provider was based on the ICriteria API).<br />Your operators are replaced with the predefined corresponding ones (or the one you defined/customized).<br />The result is the internal representation of an HQL query that is later on converted to a real SQL query.<br />Putting it simple the new provider works this way:<br />Extending Linq To NHibernate<br />
  23. 23. Create a ‘Method Generator’ – a class that basically tells Nhibernate how to build an Hql Expression that represent your Linq function.<br />Register the Method Generator in the internal methods repository – inherit from DefaultLinqToHqlGeneratorsRegistry to add you custom methods.<br />Tell Nhibernate to use your custom method registry intead of the default one:<br />To customize the provider you have to:<br />Extending Linq To NHibernate<br />
  24. 24. Inherit from the base class BaseHqlGeneratorForMethod<br />Provide the list of supported methods (a sort of call signatures)<br />Override the BuildHql() function that will provide the HqlExpression that represent your operator/function<br />Implement the IRuntimeMethodHqlGeneratorinterface (usefull when you do not know the types involved ‘at design time’).<br />you do not provide a list of function calls to match<br />Implement the  bool SupportsMethod(MethodInfo method) – states if the method can be represented by the generator.<br />Implement the IHqlGeneratorForMethod GetMethodGenerator(MethodInfo method) – returns a method generator that will be used to generate the HqlExpression<br />To create a Method Generator you can:<br />Extending Linq To NHibernate<br />
  25. 25. Demo<br />Extending the provider<br />
  26. 26. Thank you for attending!<br />