The Darkside

Shedding light on things and stuff

 
  Home :: Contact :: Syndication  :: Login
  75 Posts :: 0 Stories :: 49 Comments :: 2 Trackbacks

Ads

Archives

Post Categories

Open Source Projects

Other Blogs

Introduction

I've been having a look at the NHibernate contributions project on SourceForge and decided to give the NHibernate.Linq project a whirl. After some initial tests, I have to say I'm very impressed. There are some limitations that are actually the result of NHibernate, not the Linq project, but nothing serious enough for me not to use it.

My next logical progression was to find out how to make use of NHiberntate.Linq in Castle ActiveRecord. Some very quick searching revealed this article from Matt (http://trycatchfail.com/blog/post/2008/08/19/Using-LINQ-with-ActiveRecord.aspx) on how to build all the relevant projects, their dependencies and finally how to use it.

I followed all the steps, which are relatively straight forward once you have castle building, and managed to get a working set of binaries to start my ActiveRecord.Linq work :) I've done the build using the following revisions/versions:

NHiberntate - 2.1.0.1001 GA
NHibernate.Linq - Rev 695 (source code)
Castle Project  - Rev 5496 (source code)

Download

I've made this set of binaries available for download here for those who'd like to just get going rather.

Code

One of the additions you'll need to make to your project if you're going to use Castle ActiveRecord with NHibernate.Linq is a class that gives you access to the underlying NHIbernat.Linq context. I've modified the original example provided by Matt to better suite what I had planned for it.

 Expand Code
/// <summary>
/// Idea originally from http://trycatchfail.com/blog/post/2008/08/19/Using-LINQ-with-ActiveRecord.aspx
/// </summary>
public sealed class ActiveRecordLinqContext : NHibernateContext
{
    private ActiveRecordLinqContext() : base(GetSession()){}
 
    ///<summary>
    ///</summary>
    ///<typeparam name="T"></typeparam>
    ///<returns></returns>
    public static INHibernateQueryable<T> Linq<T>() where T: ActiveRecordBase
    {
        return (SingletonCreator.Instance.Session.Linq<T>());
    }
 
    private static class SingletonCreator
    {
        internal static readonly ActiveRecordLinqContext Instance = new ActiveRecordLinqContext();
    }
 
    private static ISession GetSession()
    {
        if (SessionScope.Current == null)
            throw new InvalidOperationException("No active SessionScope found.");
 
        return ActiveRecordMediator.GetSessionFactoryHolder().CreateSession(typeof(ActiveRecordBase));
    }
}

And you can then make use of this code like this (I've included an ActiveRecord class as well):

 Expand Code
public class TestItem: ActiveRecordBase<TestItem>
{
    [PrimaryKey (Generator = PrimaryKeyType.Identity)]
    public int Id { get; set; }
 
    [Property]
    public string ItemName { get; set; } 
 
    [Property]
    public string ItemDescription {get; set;} 
 
    public TestItem[] GetTestItemsNamedBob ()
    {
        var testItems = (from ti in ActiveRecordLinqContext.Linq<TestItem>() where ti.ItemName == "Bob" select ti).ToArray();
        return (testItems);
    }
 
 
 
    public string[] GetNamesOfAllTestItems()
    {
        var testItemNames = (from ti in ActiveRecordLinqContext.Linq<TestItem>() select ti.ItemName).ToArray();
        return (testItemNames);
    }
}

In the code above, I've have two calls; The first (GetTestItemsNamedBob()) returns an array of ItemTest classes. The linq query in that method is functionally quivalent to the following code:

public TestItem[] GetTestItemsNamedBob()
{
    var testItems = FindAll(new ICriterion[] {Restrictions.Eq("ItemName", "Bob")});
    return (testItems);
}

What is really cool is in the second method. If you turn on the show_sql in your ActiveRecord configuration, you'll notice that the sql that is actually sent to the server is ONLY for the field "ItemName", and that the data returned is simply a list of names and not all the data for all the fields, which is the case for normal NHibernate/ActiveRecord queries.

 Thanks again to Matt (and also to Ken Egozi who started Matt off in the right direction) for the idea and instructions.

posted on Saturday, January 17, 2009 12:00 AM
Comments have been closed on this topic.