Matt Enright
Matt Enright

Reputation: 7484

Can I access the NHibernate ISession instance from IQueryable?

I'm trying to wrap up a few complicated query patterns into extension methods on IQueryable<Foo> and have occasional need to do some outer joins in them.

static IQueryable<Foo> Filter(this IQueryable<Foo> foos, params string[] searchTerms)
{
    //...
    return from t in session.Query<Tags>()
           from f in foos
           where
               (t.Name.Contains (searchTerms[0] && f.Tags.Contains(t))
               || f.Name.Contains(searchTerms[0]
           select f;
}

Another case also requires the session access to do some save operations (yes, yes, side effects are bad. It's for tracking query patterns).

I've worked around this in the first case by passing in the collection of tags as an argument, which, while a bit ugly for the caller, works fine, but obviously doesn't scale, and the only other option I've been able to divine for figuring this out for the general case is to just pass the ISession in directly.

What I would love is to have some helper method like the following that I could call from the extension method:

static ISession GetSession<T> (IQueryable<T> query)
{
    // do magic
}

Even if it involves downcasting the queryable, or the query provider or something to Nh* I think I would prefer it to passing the session in. But I haven't found a way to access this (the session property on NhQueryProvider is protected). Am I missing some other way to get this out of the expression?

Upvotes: 0

Views: 563

Answers (2)

Ricardo Peres
Ricardo Peres

Reputation: 14535

You have to use reflection:

IQueryable<Product> query = Session.Query<Product>();
ISession session = query.Provider.GetType().GetProperty("Session", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(query.Provider, null) as ISession;

Upvotes: 2

J. Ed
J. Ed

Reputation: 6742

I believe you may benefit from using the QueryObject pattern-
You'll define a method that takes an ISession parameter and invokes the query on it;
You can define the different search terms using properties of your query object instead of resorting to the string array solution.

Ayende has a little cooler flavour

Upvotes: 0

Related Questions