Top Banner
LINQ2NH Ricci Gian Maria Giorgetti Alessandro
26

NHDay Introduction to LINQ2NH

Dec 06, 2014

Download

Technology

Slide of the LINQ2NH session of NHibernate Day 2010
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: NHDay Introduction to LINQ2NH

LINQ2NHRicci Gian MariaGiorgetti Alessandro

Page 2: NHDay Introduction to LINQ2NH

• Nhibernate permits you to query database with different techniques

•NHibernate support for Query

Page 3: NHDay Introduction to LINQ2NH

• The LINQ query expressed by code gets translated into an “Expression Tree”

• An Expression Tree is a representation of the query with a tree like this one

•What is needed to build a LINQ provider

 3 + (5 + 9) * 2

Page 4: NHDay Introduction to LINQ2NH

• If an arithmetic expression is simple to visualize as a tree a LINQ query could be more complex.

• Luckily enough, we do not need to know this to use LINQ2NH, but is useful to understand the process

•Expression Tree in real world

Page 5: NHDay Introduction to LINQ2NH

• We already have a LINQ2NH provider, is it not good?

•We have LINQ2NH in 2.1.. So?

Page 6: NHDay Introduction to LINQ2NH

• 2.1 LINQ provider is limited by features offered by ICriteria• The query gets translated from ExpressionTree to ICriteria then

from ICriteria to the real query• ICriteria misses some features like Having clause• It is difficult to create complex query with ICriteria so it is

difficult to support full LINQ syntax

•Current situation

LINQ ICriteria SQL

Page 7: NHDay Introduction to LINQ2NH

• First of all there was a rewrite of the HQL parser using an AST (Abstract Syntax Tree) based on ANTLR

• Steve Strong started from the Java ANTLR parser and converted for C#

• The resulting HQL engine now has four steps, the hard work is between 2nd and 3rd steps

•A new idea – use HQL

String

Parse Tree

Sql tree

Sql query

Page 8: NHDay Introduction to LINQ2NH

• The big idea is to create a provider that translate an Expression Tree to the same Parse Tree of HQL

•Why rewrite HQL parser is needed for LINQ

• The complex part, is translating the Parse tree

• Translation of parse tree is the point where mappings are consulted to generate the SQL tree

• Reusing the same code for HQL and LINQ is the key for success and performance

Page 9: NHDay Introduction to LINQ2NH

• Actually the provider supports many features, but since parsing an Expression Tree is not so simple we still have something unsupported

• We will see this in detail in the second part, you should simple be aware that not full LINQ syntax is supported

• Is LINQ2NH mature enough?

Page 10: NHDay Introduction to LINQ2NH

•WHY LINQ 2 NHIf we already have HQL, ICriteria and SQL, we really need LINQ?

Page 11: NHDay Introduction to LINQ2NH

• LINQ is strongly typed, so you have full intellisense power and compile time checking

• Refactoring capabilities, if you rename a property of a mapped class, you automatically have your LINQ queries updated

• 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.

•Difference between HQL and LINQ

Page 12: NHDay Introduction to LINQ2NH

• Some of the LINQ operator are called: “deferred” operator• A deferred operator is evaluated only during the iteration of the

content, or if you call a “not deferred” operator (like ToList() )

•Deferred execution – a key concept of LINQ

Page 13: NHDay Introduction to LINQ2NH

• The very same happens for LINQ2NH queries.

•Deferred execution – even in LINQ2NH

Nothing get executed here, you are only defining a query like you do with ICriteria

Since Count is a “non deferred” operator, a query to the database is issued.

Page 14: NHDay Introduction to LINQ2NH

• LINQ query is an expression tree that can be manipulated by code

• Like ICriteria is simple to add and remove condition, projections to an existing query.

• You can pass a LINQ query between layers, each layer can manipulate the query in a very simple way.

•Difference between HQL and LINQ

Page 15: NHDay Introduction to LINQ2NH

• Very easy projection

• You can have one layer that manage the where part and another one that use projection

• You can project into Dto (Data Transfer Object) with great easy, respect HQL

• You can leverage Anonymous Type instead of DTO.

•Difference between HQL and LINQ

Page 16: NHDay Introduction to LINQ2NH

• You can build on the fly complex anonymous DTO, with calculation in it and let the provider do the work

•LINQ is expressive

Provider is smart, and select only what is needed and not unnecessary properties

Since you want to use the year part of the BirthDate property, the provider is using datepart SQL function

Page 17: NHDay Introduction to LINQ2NH

Linq to Nh – Part 2

Page 18: NHDay Introduction to LINQ2NH

• A thing you need to be aware of…

• Some things that actually ‘do not work’

• How to extend the provider to overcome issues and add features.

•Part 2 - Agenda

Page 19: NHDay Introduction to LINQ2NH

• Nhibernate best practice: use explicit Transations!

• Deferred execution might cause troubles when coupled with Transaction Management policies.

• It’s very easy to execute code outside the scope of a transaction, and you will hardly spot it at first.

• 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…).

•A Thing to be Aware of…Linq2Nh and Transactions

Page 20: NHDay Introduction to LINQ2NH

• 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.

• 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.

• Custom IUserType(s) not supported yet. (It’s a bug and should be corrected soon..remember it’s an alpha version).

• 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.

During everyday usage of the provider you can encounter the following problems:

•Some things that actually ‘do not work’

Page 21: NHDay Introduction to LINQ2NH

• Fix some of the holes in the provider – the missing equals for example.

• Add new features and functionalities.

Extending the provider is very easy and it allows you to:

•Extending Linq To NHibernate

Page 22: NHDay Introduction to LINQ2NH

• Given your Linq Query a parser examines it.

• 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).

• Your operators are replaced with the predefined corresponding ones (or the one you defined/customized).

• The result is the internal representation of an HQL query that is later on converted to a real SQL query.

Putting it simple the new provider works this way:•Extending Linq To NHibernate

Page 23: NHDay Introduction to LINQ2NH

• Create a ‘Method Generator’ – a class that basically tells Nhibernate how to build an Hql Expression that represent your Linq function.

• Register the Method Generator in the internal methods repository – inherit from DefaultLinqToHqlGeneratorsRegistry to add you custom methods.

• Tell Nhibernate to use your custom method registry intead of the default one:

To customize the provider you have to:•Extending Linq To NHibernate

Page 24: NHDay Introduction to LINQ2NH

• Inherit from the base class BaseHqlGeneratorForMethod• Provide the list of supported methods (a sort of call signatures)• Override the BuildHql() function that will provide the HqlExpression that

represent your operator/function

• Implement the IRuntimeMethodHqlGeneratorinterface (usefull when you do not know the types involved ‘at design time’).

• you do not provide a list of function calls to match• Implement the bool SupportsMethod(MethodInfo method) – states if the

method can be represented by the generator.• Implement the

IHqlGeneratorForMethod GetMethodGenerator(MethodInfo method) – returns a method generator that will be used to generate the HqlExpression

To create a Method Generator you can:•Extending Linq To NHibernate

Page 25: NHDay Introduction to LINQ2NH

DemoExtending the provider

Page 26: NHDay Introduction to LINQ2NH

THANK YOU FOR ATTENDING!