Ayende @ Rahien

It's a girl

Developing Linq to NHibernate

I have been thinking about this for a while now. Linq to NHibernate requires two to three months of full time development work in order to get to a really good usable state. The problem is that we don't have anyone working on that full time. Considering the nature of OSS, this is not surprising, but I would like to change that if I can.

I am trying to getting sponsorship from several companies that are willing to pay for the development of Linq for NHibernate. The details are very simple, if I get enough companies interested in this to dedicate enough time & resources into it, we can get it working.

If you or your company are interested in helping fund the Linq for NHibernate project, please contact me privately, and we can discuss how we go about this.

NHibernate 2.0 and Linq

Linq for NHibernate is not part of the 2.0 release. Linq support is planned for the 2.1 release. That said, we have been getting a lot of questions about that.

The technical reasons are not really interesting, but suffice to say that to provide good Linq support we also need to modify NHibernate slightly. Those changes happens on the trunk, which is what Linq for NHibernate is following.

However, due to all the questions that we got, I wanted to point out that Daniel Guenter has back ported the current version of Linq to NHibernate to Nhibernate 2.0 and made it available here.

Now, the disclaimer. We are not supporting this. This is an unofficial (but welcome) contribution from the community. It is likely to have bugs (in fact, we know it contains bug in the more complex Linq queries, that is why it is still under active development), and the NHibernate team response is most likely going to be, use the latest, which requires the NHibernate trunk, not the NHibernate 2.0 version.

Use at your own risk, etc.

Unreadable Linq

Chad Myers has posted about the query objects with the repository pattern. He is trying to solve the problem of reusable pieces of queries that can be combined together. In theory, this gives you a way to compose queries in a way that hide the actual query logic. This is a good thing.

Unfortunately, the syntax leaves a lot to be desired:

_query = new TopCustomersWithLowDiscountQuery()
	.IncludePreferred();

var otherQuery = new DeliquentCustomersQuery()
	.WithPendingLitigation()
	.WithDebtOver(999);

var results = _customers
	.AsQueryable()
	.Where(_query.OrElse(otherQuery));

Note how you compose the queries, that is simply unreadable as the query complexity scale up. At the same time, we don't really have a better way of handling that since the from expression will not accept Expression<T> instances directly. What has me worried is the tendency toward over abstraction that I have seen in a few code bases. In particular, I have seen API that takes several Expression<T> objects and compose them in interesting ways. Here is an example:

var customers = repo.FindBy(
        new TopCustomersWithLowDiscountQuery()
            .IncludePreferred()
            .BelowDiscountThreshold(3)
            .WithMoreSalesThan(500)
        .AndAlso(
            new DeliquentCustomersQuery()
                .WithDebtOver(9999))
            
);

Oh, this is a really neat trick from a programming perspective, but it makes it very hard to read and understand the code. Try to add ordering and projections to this type of query. And then try to understand the code.

I don't have any great solutions for that, unfortunately, but it is a problem that is worth pointing out.

A better solution would be to integrate that with the Linq query provider to support extracting the expression tree from the query, but that is not practical as an overall solution.

ADO.Net Data Services with NHibernate

Shawn Wildermuth has bridged the gap between the two, implementing IUpdatable on top of Linq to NHibernate. This means that you can now expose your NHibernate domain model as a set of REST services.

This functionality is now included with Linq for NHibernate. Thanks Shawn!

There is a live sample here: http://www.silverlightdata.com/Simple/NHibernate.aspx

Or you can hit the URLs directly and see what kind of formatting it has:

From a technological perspective, I think this is awesome. However, there are architectural issues with exposing your model in such a fashion. Specifically, with regards to availability and scalability on the operations side, and schema versioning and adaptability on the development side.

ADO.Net Data Services are a very thin wrapper around a DB, and as such, they should be treated as such. Do not expose them where you wouldn't want to expose your DB as well.

Linq for NHibernate Adventures

So for the last few hours I have been getting back into the Linq for NHibernate project, after having left it for far too long. I am beginning to think that building a Linq provider might not have been the best way to learn C# 3.0, but never mind that now.

It is with great pride that I can tell you that the following query now works:

from e in db.Employees
select new { Name = e.FirstName + " " + e.LastName, Phone = e.HomePhone }

Why is this trivial query important? Well, it is important because about a year ago I said that there is only a single feature in Linq for SQL that NHibernate doesn't have. I also promised to fix it the moment that someone would tell me what it is. No one did, so it waited until today.

The main issue had to do with the Criteria API and handling parameters, no one ever needed to do that, it seems. When they did, they generally used HQL, which did have this feature. Since I have based Linq for NHibernate on the Criteria API*, that was a problem.

Now that ReSharper works on C# 3.0, I can actually get things done there, so I sat down and implemented it. It is surprisingly difficult issue, but I threw enough code on it until it gave up (I wonder if there is a name for nested visitors... ).

At any rate, I strongly recommend that you'll take a look at the project. And bug (fixes) and other patches are welcome**.

* This decision was important for two reasons, the first was that it is generally easier to use the Criteria API programmatically, and the second was that I wanted to ensure that the Crtieria API (which I favor) was a full featured as the HQL route.

** Yes, I know that I'll regret it.

The cost of inappropriate linqing

I read this post with interest, apparently Linq for SQL is doing something odd, because I can't quite believe the results that this guy is getting. From the post:

So I dug into the call graph a bit and found out the code causing by far the most damage was the creation of the LINQ query object for every call! The actual round trip to the database paled in comparison

I can't imagine what they are doing there to cause this performance characteristics.

From my own experiments with Linq, it should definitely not produce this amount of efforts.

Awkward Testability for Linq for SQL

Note: I am writing this post in the express hope that it would help to change the current situation.

I have been just recently informed about a significant problem with Linq for SQL. It doesn't support testing easily. You can see the bug report here, and as usual, it was closed as Won't Fix without even providing an explanation. Did I mention already that I don't like Connect's approach to it? Yes, I did.

The root problem is a fairly simple one. Linq for SQL relies on reams of generated code, which means that if I have code line this:

var customers = from c in context.Customers 
  select c;

Then I have no really easy way to mock what is going on in here. The generated code provides a concrete class without an interface, so it is very hard to mock, and naturally, System.Data.Linq.Table<T> is sealed, has internal stuff, and is utterly hostile to mocking.

You have to use mocking if you  want to use the code above without hitting the database, and this is a core part of the way a lot of people work. Linq for SQL doesn't take that into account.

The requirement for mocking aren't really that onerous, we need and interface generated for the context class, and interface for Table<T> and that the generated code will default to using interfaces by default (Best Practices, anyone?).

Having to write adapters classes is something that TDDers on the .Net platform has become very familiar with, because of the insistence of using untestable practices throughout the framework. I am fairly tired of that, and I would certainly like to be able to skip this tiring process for once.

It is shocking to me that in this day and age the Linq for SQL team can still believe utterly ignore such practices and put hurdles in the path of easy testability.

Are we back to demos vs. reality development?

To finish, this bug has been closed, so it is not possible even to vote for it. At the very least, I would like to hear an explanation, and it had better not involved "lack of resources".

Dreaming in Code: Multi Linq

I was asked how we will approach the same Multi Query approach with Linq integration, here are some thoughts about it.

var posts = from post in data.Posts
            where post.User.Name == "Ayende"
		orderby post.PublishedDate desc;
var postsCount = posts.Count();
posts.Skip(10).Take(15);

new LinqQueryBatch()
 .Add(posts)
 .Add(postsCount)
 .Execute();//perform the query

foreach(Post p in posts)//no query
{
  Console.WriteLine(p.ToString());
}
//no query
Console.WriteLine("Overall posts by Ayende: {0}", postsCount.Single() );

The LinqQueryBatch in this case doesn't need to pass delegates to process the results, it can modify the Linq Query directly, so trying to find the result will find the one that was already loaded when we executed the multi query.

Again, this is something that I am merely thinking about, no concrete code created.

LINQ to SQL - Dynamically Constructing Queries - Um... No!

Mike Taulty is talking about constructing queries dynamically in Linq to SQL. Sorry, but my response to that is Yuck! Here is the code that he shows:

  NorthwindDataContext ctx = new NorthwindDataContext("server=.;database=northwind");

   var query = from c in ctx.Customers
               where c.Country == "Germany"
               select c;

   if (RuntimeCriterionOneApplies()) 
   {
    query = from c in query
            where c.City == "Berlin"
            select c;
   }

   if (RuntimeCriterionTwoApplies())
   {
    query = from c in query
            where c.Orders.Sum(o => o.Freight) > 100
            select c;
   }

   foreach (Customer c in query)
   {
    Console.WriteLine(c.CustomerID);
   }

This is not constructing queries dynamically, it is choosing a query dynamically. This isn't what I talk about when I am talking about constructing a query dynamically. You can look here as what I consider a complex query that is being constructed dynamically.

Mike, how would you handle that scenario in Linq?

Update:  I really should pay more attention when I am reading the code. Sorry Mike, the code that you have will work for the scenario that I have. I don't think that the syntax is very elegant for this scenario, but it will work. I missed the "from q in query" and read is as if a new query were constructed in each if.

Linq for NHibernate: Functions

Bobby Diaz is still producing some amazing stuff. The new addition is native support for SQL functions. Take a look at this code:

DateTime date = new DateTime(1960, 1, 1);

var query = ( from e in db.Employees
                   where db.Methods.Year(e.BirthDate) >= date.Year && db.Methods.Len(e.FirstName) > 4
                   select e.FirstName )
                   .Aggregate(
new StringBuilder(), (sb, name) => sb.Length > 0 ? sb.Append(", ").Append(name) : sb.Append(name));

Console.WriteLine("Birthdays after {0}:", date.ToString("yyyy"));
Console.WriteLine(query);

Check out Bobby's post for the full details. I am going to write a full overview of the current state of Linq for NHibernate soon. The situation so far is looking very nice.

Linq for NHibernate Updates: Adding a new committer

Following several good patches, I have added Bobby Diaz to the Rhino Tools project, which currently includes the Linq for NHibernate implementation as well. I expect that the new stuff will be up in the repository shortly.

Just to remind you, I am still looking for more volunteers to help with the implementation, so if you are into futuristic technologies, just dive right into the code and the implementation details. And be sure to send me (or Bobby) a patch or two.

Linq For NHibernate: Orderring and Paging

Bobby Diaz has implemented orderring and paging support for Linq to NHibernate, so this works:

(from c in nwnd.Customers select c.CustomerID)
        .Skip(10).Take(10).ToList();

As well as this:

var query = from c in nwnd.Customers
   where c.Country == "Belgium"
   orderby c.Country descending, c.City descending
   select c.City;

Thanks again, Bobby, and the new code is on SVN.

Linq for Entities: Abstractions

Jeremy has a great post summarizing the MVP summit, and he include:

Linq for Entities is much more than an O/R Mapper.  It potentially provides us with a unified data access strategy over heterogeneous data sources (web services, xml, non relational databases, etc). 
  • Web service call is (a remote remote call - extranet/internet)
  • Non relational databases
  • Hierarchical data stores
  • Relational databases

Now consider the following query:

Customer customer = (from c in someHeterogeneousDataSource.Customers
   where c.Name == "Ayende" select c).First();
  • If the web service expose a GetCustomerByName(), this would be a good candidate, if not, the implementation would need to call GetAllCusomters() and filter it in memory.
  • For non relational databases, I am aware of object databases, flat files, temporal and hierarchical (covered seperatedly) - each of which has its own tradeoffs. I am not familiar with object databases to say what the tradeoffs are here, but for a flat file, it is going to be a linear scan. The query is not even a valid one for a temporal database (unless there is an implict CurrentTime).
  • For hierarchical data stores, this query would need to iterate all the customers, and compare their name to the query.
  • Relational database would think that this is too easy, and quit.

And this is just about the simplest query possible. I can't guess what will happen if I happened to want a join between customer and orders.

I get the feeling that I am missing something here, because it sure isn't heterogeneous to me.

Linq for NHibernate Updates

I got a couple of great patches yesterday and today, Bobby Diaz sent a patch to add support for Count() and DataContext like behavior. Jon Stelly went and cleaned up my code, turning it from a sleep-deprived hack into a respectable project. You can see his full list here. Thanks to their efforts, this now works:

(from user in orm.Users select user).Count();

I changed the implementation of NHibernteLinqQuery to use the visitor pattern, which is the natural way that I think about walking through an AST. It is still very primitive one, but it does the job that we need right now.

The new code is in the repository:

Bobby and Jon, thanks again. Everyone else, you are invited to the party as well.

Linq: Possibilities

Jeff Brown commented on my Linq Options post:

Pity they didn't shoot for lexically-scoped blocks a la SmallTalk (or Ruby)...  This approach with Expressions has the same control-flow limitations as anonymous delegates but you can omit the curly braces sometimes.

Linq is not just anonymous delegates. (I should be clear that I am mostly thinking about the abilities of Expression rather than the Langague Integrated Query here). It means that I can start doing some really stuff. For what it worth, there is such a thing as the ExecutionScope for linq, but I am not sure what it is supposed to do, as far as I can see, it is the entire lexical scope for the expression.

Here is a trivial example that shows what you can do with it. Assume that I have this work item (and saved action):

[Serializable]
public class WorkItem

{

    string name;

    string action;

    string on;

 

    public WorkItem(string name, string action, string on)

    {

        this.name = name;

        this.action = action;

        this.on = on;

    }

    public WorkItem() {}

 

    public void DoAction()

    {

        Console.WriteLine(name +" "+action+" " +on);

    }

}

 

[Serializable]
private class SavedAction
{
   public object target;
   public string method;
}

And I have this code:

public delegate void Act();

static void Main(string[] args)
{
    WorkItem wi = new WorkItem("Ayende,", "write", "blog post");
    Save("Temp.action",() => wi.DoAction());
    Act act = Load("Temp.action");
    act();
}

What is going on here? I am saving the labmda into a file in the Save(), then load and execute it in the next two statement. Sadly, Linq's Expression<T> are not serializable, which I consider a huge minus, but for this example, I worked around it a bit. Here is the code for the Load, which isn't really interesting:

private static Act Load(string file)
{
    SavedAction action;
    BinaryFormatter bf = new BinaryFormatter();
    using (Stream s = File.OpenRead(file))
        action = (SavedAction)bf.Deserialize(s);
    return (Act)Delegate.CreateDelegate(typeof(Act), action.target,
        action.target.GetType().GetMethod(action.method));
}

The Save() is where the real magic begins, I compile the expression, extract the target, extract the method that was about to call, and save it, for later processing in the load.

private static void Save(Expression<Act> actionToSave)
{
    Act act = actionToSave.Compile();
    ExecutionScope scope = (ExecutionScope)act.Target;
    SavedAction action = new SavedAction();
    MethodCallExpression l = (MethodCallExpression)actionToSave.Body;
    action.target = Expression.Lambda(l.Object).Compile().DynamicInvoke();
    action.method = l.Method.Name;
    BinaryFormatter bf = new BinaryFormatter();
    using(Stream s = File.Create("Temp.action")) 
        bf.Serialize(s, action);
}

I am very excited about these capabilities. Yes, I can do it today, but the inteface I would have to expose is wholly unatural, while Linq provide for much nicer alternative.

Implementing Linq for NHibernate: A How To Guide - Part 1

There is an appaling lack of documentation about how to implement Linq providers. The best resource that I could find is Fabrice's post about Linq To Amazon. The Linq In Action may provide additional information, but from what I have seen it is about using linq, not build a provider yourself. Since I would really like people to pitch in and help with the implementation of Linq for NHibernate (not that this is a hint or anything), I decided to document what I found out while building Linq for NHibernate.

I strongly suggest that you would get the VPC Image and use that to explore what is possible. The code, to remind you, is at:

svn co https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/experiments/NHibernate.Linq/

My goal at the moment is feature parity with the 101 examples that Microsoft have published.

I am not going to explain in detail how Linq works, you can go to other sites to find that out, but here is a short introduction. Linq is an extention to the compiler that turns certain keywords into method calls. The interesting part it that the compiler can give you the AST (Abstract Syntax Tree) for the query instead of executable code. This is important, because then you are free to take actions based on the AST (for instance, make a database call).

The whole concept revolves around two main ideas, IQueryable<T> and Expression which are tightly linked together. The compiler will output an Expression tree that will be passed to the IQueryable<T> implementation. Of course, there need to be an IQueryable<T> implementation, and that is where extention methods come into place. I implemented to core functionalty by adding an extention method to ISession, like this:

public static class LinqForNHibernate

{

    public static IQueryable<T> Linq<T>(this ISession session)

    {

        return new NHibernateLinqQuery<T>(session);

    }

}

Now I can execute this query, and NHiberanteLinqQuery get to intercept the expression tree:

var query = (from user in session.Linq<User>() select user).ToList();

The rest of this post is going to focus mostly on the NHibernateLinqQuery implementation. I have choosen to base the Linq implementation on the criteria API. This make the task a lot simpler, since I can let mature API handle a lot of the underlying query generation. The criteria API does not exposes 100% of the functionality offered by NHibernate, but it offers most of it, and saves me the need to handle query generation myself. Where I would need features in the criteria API that do not currently exists, I can add them.

Here are the fields on NHibernateLinqQuery:

ISession session;

ICriteria rootCriteria;

IDictionary<ExpressionType, Action<System.Linq.Expressions.Expression>> actions;

Stack<IList<NHibernate.Expression.ICriterion>> criterionStack = new Stack<IList<NHibernate.Expression.ICriterion>>();

IList<TResult> result;

The session and rootCriteria are probably obvious, but actions require an explanation. Each Expression has an ExpressionType, and the action dictionary contains the matching methods that can handle them. Basically, each ExpressionType is handled by a method Process[ExpressionType] on the NHibernateLinqQuery. Here is an example of the method that handles ExpressionType.Lambda:

public void ProcessLambda(Expression expr)

{

    LambdaExpression lambda = (LambdaExpression)expr;

    ProcessExpression(lambda.Body);

}

Where ProcessExpression is implemented as:

public void ProcessExpression(Expression expr)

{

    actions[expr.NodeType](expr);

}

Basically a visitor pattern with the actions dictionary serving as the dispatcher.

The criterionStack contains all the current predicates about the query. It is a stack of a list of ICriterion, and the idea is that I can insert a new list to the stack, have it process some of the expression, and then pop the list and use the processed items. Let us see this in code, we have the CurrentCritetions, which all the Process[ExpressionType] will handle, which is simply:

public IList<NHibernate.Expression.ICriterion> CurrentCriterions

{

       get { return criterionStack.Peek(); }

}

Once we have both of those, we can then use it for complex expression, like handling [user.Name == "ayende" || user.Name = "rahien"]:

public void ProcessOrElse(Expression expr)

{

       BinaryExpression and = (BinaryExpression) expr;

       criterionStack.Push(new List<NHibernate.Expression.ICriterion>());

       ProcessExpression(and.Left);

       ProcessExpression(and.Right);

       IList<NHibernate.Expression.ICriterion> ors = criterionStack.Pop();

 

       NHibernate.Expression.Disjunction disjunction = new NHibernate.Expression.Disjunction();

       foreach (var crit in ors)

       {

              disjunction.Add(crit);

       }

       CurrentCriterions.Add(disjunction);

}

We push a new list to the stack, process the right and left expressions of the or, pop the current critetion list, and then we combine them into a disjunction, which we push into the original criterion list. This way we don't have to worry about complex expression, they are mostly handled by themselves.

Now that I talked about how I am parsing the expression tree, let us talk about how the query is handled. Again, this isn't documented that I have seen, so I am mainly talking about what I discovered. The first thing that happens is that the IQueryable<T>.Expression property is called. Basically it is asked to give what sort of an expression should handle this query. I choose to handle the query in the same IQueryable<T> implementation, so I am returning this reference:

public System.Linq.Expressions.Expression Expression

{

       get { return System.Linq.Expressions.Expression.Constant(this); }

}

Then, the CreateQuery<TElement> method is called. it is important to understand the difference in the <T>'s here. The query itself is a generic type, NHibernateLinqQuery<TResult>, where TResult is the entity that we are querying. The result of the query may be different than TResult, because we may use projection to get only some of the values, or select a child item values.

Therefor, we need to return a new IQueryable<TElement>, which is why I am creating a new instance of the same class, passing it the current state of the objects, and continue to parse the expression tree.

As you can see, I am only handling the Select and Where methods at the moment. My naming convention at the moment is "HandleXyzCall" is to handle a query method, while "ProcessXyz" it to process an expression type.

public IQueryable<TElement> CreateQuery<TElement>(System.Linq.Expressions.Expression expression)

{

       MethodCallExpression call = (MethodCallExpression) expression;

       switch (call.Method.Name)

       {

              case "Where":

                     HandleWhereCall(call);

                     break;

              case "Select":

                     HandleSelectCall(call);

                     break;

       }

 

       foreach (var crit in CurrentCriterions)

       {

              rootCriteria.Add(crit);

       }

       return new NHibernateLinqQuery<TElement>(session, rootCriteria);

}

The HandleWhereCall is very simplistic, it just process all the arguments passed to the where clause:

private void HandleWhereCall(MethodCallExpression call)

{

       foreach (Expression expr in call.Arguments)

       {

              ProcessExpression(expr);

       }

}

The select method is a bit more complex, since it need to handle projections and other various interesting features. I am not going to show it here, because it is over 50 lines of codes and it is very state machine like. Not really interesting.

Linq for NHibernate

The code that I am going to show is working code. I have it passing tests on the March 2007 CTP, against NHibernate 1.2 CR1.

Select entity and filter:

var query = (
         
from user in session.Linq<User>()
          
where user.Name == "ayende"
          
select user
      ).ToList();

Project a property:

var query = (
      
from user in session.Linq<User>()
       
select user.Name
     ).ToList();

Project anonymous type:

var query = (
        
from user in session.Linq<User>()
         
select new { user.Name, user.RegisteredAt }
     ).ToList();

Where do you get that?

You can get the source from Subversion:

svn co https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/experiments/NHibernate.Linq/

You can also download it from the download page.

Caveats:

  • It is by no means a complete Linq implementation. The 101 examples for Linq are a good test metric to go against, in my opinion, and I am only hitting 13 of them right now (probably more, but I have tests for 13).
  • I read the C# 3.0 spec when it was out in PDC '06, and last night I got the March CTP and started working on an implementation. This is literally my baby steps with Linq.
  • I am not going to invest a lot of time in this. It is still far into the future, and I mostly did it to make people stop wishing for it.

Important - patches:

I would appriciate it if you will send bug reports with patches to fix them.

Have fun, and don't make too much out of it.

Playing with Orcas

As usual, just a set of random impressions:

  • Anonymous types are annoyingly limited. You can't define arrays of anonymous types, for instnace, which can open up more options for intent revealing code.
  • Linq seems to be heavily based around the idea of Expression, a lot of the stuff that is going on there revolves around Expression and operation on Expressions.
  • Here is a new way to assert that a collection contains all the items that it should:
    Assert.AreEqual(3, list.Intersect(new string[]{"ayende","rahien","bar"}).ToList().Count);
  • I am annoyed that this doesn't work, though:
    Assert.AreEqual(3, list.Intersect({"ayende","rahien","bar"}).ToList().Count);
    Shouldn't this be handled by the collection initializer?

 

Handling Dynamic Queries with the Entity Framework

Insomniac dreams. I am awake since about 2:30 AM (it is 07:30AM now), which meant that I had a chance to read my feeds, catch on my emails, do some OSS work, release a new beta and post too much :-). Just thought that I should explain why you see so many posts all of a sudden.

Anyway, the reason for this post is asking how the ADO.Net Entity Framework will handle dynamic queries. I am talking about something like this example. I just read John's post about the Entity Framework, and the question just came up in my mind.

Linq-Fu

Jafar Husain certainly knows his Linq-Fu, and he has some amazing stuff about what Linq will enable you to do.

Recommended reading.

Tags:

Published at

What would happen to NHibernate after Linq ships?

I was asked this question, and I think that the answer is interesting enough to post here.

There are two sets of technologies that MS is currently pushing.
There is Linq, which is additional support for querying directly from the language, and there is the various ORM efforts that Microsoft is pushing.
When the Linq bits will stabilize to the point where it is viable to start projects using them, there will be support for querying NHibernate with Linq.
I have looked in detailed into the four (or is it five now?) ORM efforts that microsoft is currently pushing, and I am not seeing anything that excites me there.
Early feedback that I got from Microsoft confirmed that even ADO.Net for Entities, which is the only ORM effort that tries to match NHibernate's capabilities, is not going to be extensible enough to support what I and my customers needs. This is the usual 80% solution, with a hood welded shut in all the interesting locations.
In addition to this, I find the whole configuration schema to be an order of magnitude more complex than it needs to be, with the additional complexity that this would bring later on when trying to understand what it means.

So no, I do not believe that Microsoft pushing their ORM efforts would have a bad affect on NHibernate, and having Linq would just make our life that much easier.

That said, an ORM that comes from Microsoft is probably going to be popular because it comes from Microsoft. I believe that this will merely confirm for many in the .NET world that ORM is a valid way to work.
The same people that are currently using or evaluating NHibernate will keep it, those that would never use a non Microsoft tool would use the MS ORM. Not that much different from now. People trying to migrate all but the simple projects from NHibernate to MS' ORM would run into the afore-mentioned brick walls, and would either keep using NHibernate, or would have to invest significant effort porting the application.

Is Linq For Mortals?

Mike Taulty has posted about Linq syntax, at the end, he shows a simple way to do joins and then aggregation between two collections. The code looks like this:

var a = products.Join(
      
sales,
        p => p.Id,
        s => s.ProductId,
      (p,s) => new { Country=s.Country, Sales=s.Sales, Product=p.Name })
.GroupBy( p => new { p.Country, p.Product })
.Select( gp => new { gp.Key, TotalSales = gp.Sum(s => s.Sales) });

I am sorry, but I cant read this. I can't even understand what this is meant to do. Now, I am the first to admit that my knowledge of Linq is weak at best, but still... Assume that I have a bug in such a code, how do I debug it?

That is a much bigger concern to me, I am not worried about learning the new stuff, I am worried about what I need to do when they break. I have some experiance in debugging applications via Reflector, and that is not nice. Especially if the compiler is doing funky magic and you are left reading the IL.

Bringing it all together: Even More Magic,

So, I had done a couple of fairly cool stuff recently, but it is all in seperated pieces, let us try to bring them together and see what we get, shall we?

ProjectionQuery<User> query =

       new ProjectionQuery<User>(Where.User.Name.Like("Ayende", MatchMode.Start),

                                 ProjectBy.User.Name && ProjectBy.User.Email);

foreach (object[] objects in query.Execute())

{

       Console.WriteLine("Name: {0}, Email: {1}", objects[0], objects[1]);

}

That is nice, isn't it? Again, we can use the strongly typed version to be type safe and avoid the use of arrays as DTO:

ProjectionQuery<User, NameAndEmail> query2 =new ProjectionQuery<User, NameAndEmail>(

       Where.User.Name.Like("Ayende", MatchMode.Start),

       ProjectBy.User.Name && ProjectBy.User.Email);

foreach (NameAndEmail nameAndEmail in query2.Execute())

{

       Console.WriteLine("Name: {0}, Email: {1}", nameAndEmail.Name, nameAndEmail.Email);

}

And yes, this is filed under Linq as well.