Translating NHibernate LINQ query to SQL
When working with stateless sessions in NHibernate we need some way to see generated SQL but we cannot use simple tricks as custom NHibernate interceptor to log SQL queries. As I’m using mostly NHibernate LINQ these days I was interested in how to get SQL out from LINQ query without actually executing it. Here’s my solution.
ToSql() extension method
I wrote simple ToSql() extension method for IQueryable generated by NHibernate LINQ. It also writes out parameters.
public static class NHibernateExtensions
{
public static string ToSql(this IQueryable query)
{
var provider = query.Provider as DefaultQueryProvider;
if(provider == null)
{
return null;
}
var sessionImpl = provider.Session;
var factory = sessionImpl.Factory;
var linqExpression = new NhLinqExpression(query.Expression, factory);
var translatorFactory = new ASTQueryTranslatorFactory();
var translator = translatorFactory.CreateQueryTranslators(linqExpression, null, false, sessionImpl.EnabledFilters, factory).First();
var parameters = linqExpression.ParameterValuesByName.ToDictionary(x => x.Key, x => x.Value.Item1);
var result = translator.SQLString;
foreach (var parameter in parameters)
{
result += "\r\n" + parameter.Key + ": " + parameter.Value;
}
return result.Trim();
}
}
ToSql() extension method uses only classes needed to translate LINQ expression tree to SQL.
Using ToSql() extension method
The following piece of code shows how to use ToSql() extension method. To find out more about my IDataMapper interface that mimics DbContext of Entity Framework Core, please read my blog post NHibernate on ASP.NET Core.
var projectQuery = _dataMapper.AsNoTracking()
.Projects
.Fetch(c => c.Customer)
.Fetch(c => c.Mediator)
.Where(p => p.Id == id);
var projectSql = projectQuery.ToSql();
var projects = await projectQuery.FirstOrDefaultAsync();
When projectSql variable is evaluated the query is not executed. It is only translated to SQL. Query is executed when projects variable is evaluated as then data is actually asked from projectQuery.
Here’s the result of ToSql() extension method.
select
project0_.Id as id1_2_0_,
customer1_.Id as id1_1_1_,
customer2_.Id as id1_1_2_,
project0_.Title as title2_2_0_,
project0_.ProjectKey as projectkey3_2_0_,
project0_.IsActive as isactive4_2_0_,
project0_.CustomerId as customerid5_2_0_,
project0_.MediatorId as mediatorid6_2_0_,
project0_.Deadline as deadline7_2_0_,
project0_.Description as description8_2_0_,
customer1_.Name as name2_1_1_,
customer2_.Name as name2_1_2_
from
Projects project0_
left outer join Customers customer1_ on
project0_.CustomerId=customer1_.Id
left outer join Customers customer2_ on
project0_.MediatorId=customer2_.Id
where
project0_.Id=?
p1: d9571e6b-fa73-4553-9c90-57aa7c050298
NB! ToSql() extension method doesn’t give formatted SQL. It gives it like it is for executing. You can use Poor Man’s T-SQL Formatter service to format queries returned by ToSql() extension method.
Wrapping up
Translating NHibernate LINQ expression tree to SQL without executing query against database server is trick we can use to investigate generated SQL when writing complex queries. I’m using ToSql() extension method also when optimizing slow queries to find out what was actually generated by NHibernate. For more serious work I recomment using advanced tools to monitor NHibernate.
Pingback:Dew Drop – September 1, 2020 (#3266) | Morning Dew
Pingback:The Morning Brew - Chris Alcock » The Morning Brew #3060
It’s not the final SQL and parameters are not really easy to check. You can get the actual DBCommand using the following code: https://stackoverflow.com/a/55517893/9667775
Your article helped me a lot, is there any more related content? Thanks!
Thanks for sharing. I read many of your blog posts, cool, your blog is very good.
먹튀검증 완료! 안전 토토사이트 추천
s34ryj
xo5xzr
o1ka48
토토사이트 추천
Your article helped me a lot, is there any more related content? Thanks!
Your article helped me a lot, is there any more related content? Thanks!
Your point of view caught my eye and was very interesting. Thanks. I have a question for you.
Can you be more specific about the content of your article? After reading it, I still have some doubts. Hope you can help me.
j3f3pg
Thank you for your sharing. I am worried that I lack creative ideas. It is your article that makes me full of hope. Thank you. But, I have a question, can you help me?
an15a8
8v7diw
Your writing has a way of making even the most complex topics accessible and engaging. I’m constantly impressed by your ability to distill complicated concepts into easy-to-understand language.
Can you be more specific about the content of your article? After reading it, I still have some doubts. Hope you can help me.
ptwenr
8lpzex
8vjsw3
I don’t think the title of your article matches the content lol. Just kidding, mainly because I had some doubts after reading the article. https://accounts.binance.com/el/register-person?ref=IQY5TET4
I don’t think the title of your article matches the content lol. Just kidding, mainly because I had some doubts after reading the article.
Can you be more specific about the content of your article? After reading it, I still have some doubts. Hope you can help me. https://accounts.binance.com/sl/register-person?ref=OMM3XK51
Can you be more specific about the content of your article? After reading it, I still have some doubts. Hope you can help me. https://accounts.binance.info/en/register?ref=JHQQKNKN
I don’t think the title of your article matches the content lol. Just kidding, mainly because I had some doubts after reading the article.
xhi1bx
I don’t think the title of your article matches the content lol. Just kidding, mainly because I had some doubts after reading the article.
Thank you very much for sharing, I learned a lot from your article. Very cool. Thanks.
Thank you very much for sharing, I learned a lot from your article. Very cool. Thanks.
Thanks for sharing. I read many of your blog posts, cool, your blog is very good.
I don’t think the title of your article matches the content lol. Just kidding, mainly because I had some doubts after reading the article.
g942xy
Their strain selector could be an evolved version of ancient Ayurvedic typologies.
15f8vx
탑플레이어포커 머니상: https://www.pokertopplayer.com/
토토사이트 토토천국
Your article helped me a lot, is there any more related content? Thanks!
Can you be more specific about the content of your article? After reading it, I still have some doubts. Hope you can help me.
5ld175