﻿<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Ayende @ Rahien</title><link>http://ayende.com</link><description>Ayende @ Rahien</description><copyright>Copyright (C) Ayende Rahien  2004 - 2021 (c) 2026</copyright><ttl>60</ttl><item><title>Fred commented on NHibernate 2.0 and Linq</title><description>....Why using Nhibernate to emulate MS ORM (or whatever they call it)
  
  
I can't see why Nhibernate would require Linq support...
  
It could probably help out some people who do not really require an ORM.
  
  
When will you supply fetching strategy in Linq ?
  
When will you supply multiple returns with specific fetching strategy ?
  
Attaching / Detaching ?
  
  
HSQL / ICriteria / IQuery are far more powerfull.
  
  
I understand when you are using LLBL that queries would benefit from linq support, but nhibernate...
  
  
At least, the most interesting features is still available : 
  
Linq to object on query results if required.
  
  
the same way as automated mapping it's a waste of time.
  
How intelligent and powerfull, no tool can understand business requirements from data model.
  
Except northwind or petshops....
</description><link>http://ayende.com/3592/nhibernate-2-0-and-linq#comment15</link><guid>http://ayende.com/3592/nhibernate-2-0-and-linq#comment15</guid><pubDate>Wed, 22 Oct 2008 15:45:10 GMT</pubDate></item><item><title>Mike commented on NHibernate 2.0 and Linq</title><description>with the current nh.linq contrib are subqueries like this possible?  I cant seem to get them to work
  
  
from c in Customers
  
select new
  
{
  
	c.Name,
  
	Purchases =
  
		from p in Purchases
  
		where p.CustomerID == c.ID &amp;&amp; p.Price &gt; 1000
  
		select new { p.Description, p.Price }
  
}
</description><link>http://ayende.com/3592/nhibernate-2-0-and-linq#comment14</link><guid>http://ayende.com/3592/nhibernate-2-0-and-linq#comment14</guid><pubDate>Sun, 19 Oct 2008 21:48:40 GMT</pubDate></item><item><title>Ayende Rahien commented on NHibernate 2.0 and Linq</title><description>EntityRef and EntitySet ?
  
Why are they interesting?
</description><link>http://ayende.com/3592/nhibernate-2-0-and-linq#comment13</link><guid>http://ayende.com/3592/nhibernate-2-0-and-linq#comment13</guid><pubDate>Mon, 15 Sep 2008 00:36:26 GMT</pubDate></item><item><title>Humberto C Marchezi commented on NHibernate 2.0 and Linq</title><description>Hi,
  
  
Do you plan to support EntityRef and EntitySet in future NH releases ?
  
  
I know I can use this in my current NH version but it will actually ignore it but the reason I ask this is because proxies can be a headache sometimes when I have to work with casting involving objects that are part of class hierarchies or when I have to inspect objects in Visual Studio debug mode.
  
  
  
  
  
  
</description><link>http://ayende.com/3592/nhibernate-2-0-and-linq#comment12</link><guid>http://ayende.com/3592/nhibernate-2-0-and-linq#comment12</guid><pubDate>Mon, 15 Sep 2008 00:26:39 GMT</pubDate></item><item><title>Frans Bouma commented on NHibernate 2.0 and Linq</title><description>Sure, tests are needed, to see if what you wrote even works and you were right about what you thought should work ;). We use them too. They're also a lock on the door when you do change something, but shouldn't give that much confidence in this case, as everything works so much together. 
  
  
Ideally, one would use different visitors / handlers for different subtrees, e.g. a tree inside a projection is a different scope and therefore different visitors could be used. This leads to more isolation of the problems which arise, however it also runs the risk of duplicated code: often a handler might look the same as in other scopes. In practise this thus leads to a single handler for a single pass. Problem is that a handler for a given expression type E is therefore used in different scopes so changing it affects ALL these scopes. 
  
  
Due to no documentation at all and no standard whatsoever for expression trees (so be prepared for running your code with VB.NET as that compiler creates different trees) it's unknown in which scopes an expression could pop up and therefore in which scopes a change has any effect or SHOULD have any effect or not. I learned in the past few months that that was the main cause for a lot of the bugs we ran into. Unfortunately, it's hard to solve that problem other than simply try/error rinse repeat....
</description><link>http://ayende.com/3592/nhibernate-2-0-and-linq#comment11</link><guid>http://ayende.com/3592/nhibernate-2-0-and-linq#comment11</guid><pubDate>Fri, 12 Sep 2008 17:11:43 GMT</pubDate></item><item><title>Tuna Toksoz commented on NHibernate 2.0 and Linq</title><description>Frans, I read your blog and enjoy them a lot. I took your first one offensive, maybe just because I were sensitive yesterday. I'll(and the team) follow your advice, but right now I am trying to have something work with NH(it is a simple query with where f.SerialNumber=="someserial". This is not related with Linq directly, but related with NHibernate, I am trying to understand it.
  
  
Thanks for your comments, they mean a lot for me.
  
  
And for tdd case, you are right but i think that it is best to have queries test as we did in Contrib Linq. The simple expression reducers are just to warm up.
  
  
</description><link>http://ayende.com/3592/nhibernate-2-0-and-linq#comment10</link><guid>http://ayende.com/3592/nhibernate-2-0-and-linq#comment10</guid><pubDate>Fri, 12 Sep 2008 16:26:19 GMT</pubDate></item><item><title>Frans Bouma commented on NHibernate 2.0 and Linq</title><description>ARGGG... Tuna, I wrote a very lengthy reply and when I clicked submit I got:
  
  
Source Error:
  
  
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
  
  
Stack Trace:
  
  
[InvalidOperationException: Sorry, but we cannot accept this comment.]
  
   Subtext.Web.UI.Controls.PostComment.LastDitchValidation() +148
  
   Subtext.Web.UI.Controls.PostComment.btnSubmit_Click(Object sender, EventArgs e) +65
  
   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +111
  
   System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +110
  
   System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
  
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
  
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +175
  
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1565
  
  
clicking 'back' revealed an empty form :X. 
  
  
Very short recap: I didn't want to discourage you, I gave you advice even (the alias objects). Please read my blog about articles writing linq to llblgen pro to read about some details of how to write such a provider. 
  
  
The reason I posted my post above was that I made the exact same mistake. You'll realize that it's wrong because parameters are only unique inside a lambda. If you use extension methods instead of 'from' or 'where', you'll realize that you can use the same parameter name over and over. 
  
  
It's a lot of work, so do realize that you'll run into a lot of problems to overcome. Try to convert the tree in multiple passes into elements you can match in a visitor. E.g. method call to Where into WhereExpression (class you write yourself) etc. During multiple passes, the tree then reduces into elements which are mergeable into a single query. I don't think NH core code has to change at all for this, unless it hasn't projection to custom type code. 
  
  
My provider is about 1.2MB of C# code, so it's a lot of code to cover almost everything. And even then I still ran into problems like this one:
  
http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=14181
  
which took me 2 weeks to fix (about 5 days full time work on and off). it's therefore key to first understand what to do to reduce subtrees into an expression you can match and recognize immediately. Use a visualizer to visualize the trees in a treeview with extra info so you can easily see how the tree reduced with each step, something like this:
  
http://weblogs.asp.net/fbouma/archive/2007/10/30/developing-linq-to-llblgen-pro-part-8.aspx
  
  
It's a modified debugger visualizer which is inside the C# examples. 
  
  
Take one step at a time, and try to understand first what's going on, what's the reason the tree looks like that and not differently. This time, forget TDD altogether at first, TDD won't bring you a good provider in this case, as refactoring a linq provider is simply very very difficult because altering code for some expression can make it fail in another situation you haven't anticipated in a test, even if you have thousands of tests. 
</description><link>http://ayende.com/3592/nhibernate-2-0-and-linq#comment9</link><guid>http://ayende.com/3592/nhibernate-2-0-and-linq#comment9</guid><pubDate>Fri, 12 Sep 2008 08:51:30 GMT</pubDate></item><item><title>Fabio Maulo commented on NHibernate 2.0 and Linq</title><description>Strange... very strange....
  
The port of NHLQ of NH.Contrib was ported outside NH.Contrib and is "unofficial" ?
  
Why "unofficial" and why out side NH.Contrib ?
  
No info about this in NHForge ?
  
Bah?!??!?
</description><link>http://ayende.com/3592/nhibernate-2-0-and-linq#comment8</link><guid>http://ayende.com/3592/nhibernate-2-0-and-linq#comment8</guid><pubDate>Fri, 12 Sep 2008 01:54:52 GMT</pubDate></item><item><title>Tuna Toksoz commented on NHibernate 2.0 and Linq</title><description>Frans, the problem is not only expression tree-sql parsing but also NH codebase.
  
NH codebase is just huge! Expression tree-sql also hard.
  
I take this as personal since this piece of code was written by me, and I don't say it will owrk perfect. It is at its early baby steps.
  
  
You may easily see what will work and what not, but i can't see. Please be encouraging, not discouraging.
</description><link>http://ayende.com/3592/nhibernate-2-0-and-linq#comment7</link><guid>http://ayende.com/3592/nhibernate-2-0-and-linq#comment7</guid><pubDate>Thu, 11 Sep 2008 16:54:55 GMT</pubDate></item><item><title>Jan Limpens commented on NHibernate 2.0 and Linq</title><description>what is "the old batch"?
</description><link>http://ayende.com/3592/nhibernate-2-0-and-linq#comment6</link><guid>http://ayende.com/3592/nhibernate-2-0-and-linq#comment6</guid><pubDate>Thu, 11 Sep 2008 15:20:09 GMT</pubDate></item><item><title>Ayende Rahien commented on NHibernate 2.0 and Linq</title><description>  Krzysztof,
  
When it is ready
</description><link>http://ayende.com/3592/nhibernate-2-0-and-linq#comment5</link><guid>http://ayende.com/3592/nhibernate-2-0-and-linq#comment5</guid><pubDate>Thu, 11 Sep 2008 14:02:36 GMT</pubDate></item><item><title>Frans Bouma commented on NHibernate 2.0 and Linq</title><description>Code like this:
  
protected Expression TransformSelectCall(MethodCallExpression expr)
  
{
  
	Expression source = this.Visit(expr.Arguments[0]);
  
	LambdaExpression lambda = LinqUtil.StripQuotes(expr.Arguments[1]) as LambdaExpression;
  
	Expression body = lambda.Body;
  
	ParameterExpression parameter = lambda.Parameters[0];
  
	string alias = parameter.Name;
  
	System.Type type = lambda.Body.Type;
  
	System.Type resultType = typeof(IQueryable&lt;&gt;).MakeGenericType(type);
  
	return new SelectExpression(resultType, alias, body, source, null);
  
}
  
  
will never succeed. The problem is that parameter -&gt; source tracking has to take place. You can't simply re-use the parameter name, as a parameter can be named equally in every new lambda in the query. You therefore need indirection alias objects: objects you use as an alias which refer to the set you want to refer to. 
  
  
This particularly flaps in your face with queries with for example SelectMany calls joining Join results etc.where also where clauses are referring to the left/right side of the SelectMany calls. 
  
  
Writing a linq provider is no picknick. After 9 months full time development we still have edge cases not working here and there, however they tend to fall into the more bizarre category with a lot of nested froms used with defaultIfEmpty on joined sets and mulitple hops (e.a.b.c.Foo==bla) combined with where clauses which have to be moved around in the query (but not always). 
  
  
My advice to you: continue with the old batch, it had more potential. 
  
</description><link>http://ayende.com/3592/nhibernate-2-0-and-linq#comment4</link><guid>http://ayende.com/3592/nhibernate-2-0-and-linq#comment4</guid><pubDate>Thu, 11 Sep 2008 11:15:16 GMT</pubDate></item><item><title>Krzysztof Koźmic commented on NHibernate 2.0 and Linq</title><description>What's the expected timeframe for 2.1?
</description><link>http://ayende.com/3592/nhibernate-2-0-and-linq#comment3</link><guid>http://ayende.com/3592/nhibernate-2-0-and-linq#comment3</guid><pubDate>Thu, 11 Sep 2008 10:52:37 GMT</pubDate></item><item><title>Rainer Schuster commented on NHibernate 2.0 and Linq</title><description>Grabbed the actual contrib trunk. 
  
  
1. delete the refenrece to the nhibernate.dll  and add the new one from the TunasExperiment\NHibernate.Linq\lib directory. 
  
  
2. modify app-config to your local mashines Sql-Server
  
  
3. Have fun
</description><link>http://ayende.com/3592/nhibernate-2-0-and-linq#comment2</link><guid>http://ayende.com/3592/nhibernate-2-0-and-linq#comment2</guid><pubDate>Thu, 11 Sep 2008 09:53:08 GMT</pubDate></item><item><title>Tuna Toksoz commented on NHibernate 2.0 and Linq</title><description>Contrib Trunk. Linq on NH trunk doesn't have a single passing query test yet.
</description><link>http://ayende.com/3592/nhibernate-2-0-and-linq#comment1</link><guid>http://ayende.com/3592/nhibernate-2-0-and-linq#comment1</guid><pubDate>Thu, 11 Sep 2008 04:20:34 GMT</pubDate></item></channel></rss>