tags:

views:

536

answers:

3

I am currently using Linq to NHibernate (although that is not an issue with regards to this question) to execute queries against my database and I want to be able to test whether the current IQueryable result instance has been executed or not.

The debugger knows that my IQueryable has not been 'invoked' because it tells me that expanding the Results property will 'enumerate' it. Is there a way for me to programattically identify that as well.

I hope that makes sense :)

A: 

I believe you can use DataContext.Log to log everything that is executed.

Christian Hagelid
I actually have no DataContext as I am using Linq to NHibernate.
berko
A: 

Assuming you're using Visual Studio, you can insert DataContext.Log = Console.Out into your code. You can then watch the SQL as it's executed, in the output window.

I'm not sure whether it's possible to programatically test whether the query has been executed. You can force it to execute, for example by calling .ToList on the query.

Mark Pattison
+1  A: 

How about writing an IQueryable wrapper like this:

class QueryableWrapper<T> : IQueryable<T>
{
    private IQueryable<T> _InnerQueryable;
    private bool _HasExecuted;

    public QueryableWrapper(IQueryable<T> innerQueryable)
    {
        _InnerQueryable = innerQueryable;
    }

    public bool HasExecuted
    {
        get
        {
            return _HasExecuted;
        }
    }

    public IEnumerator<T> GetEnumerator()
    {
        _HasExecuted = true;

        return _InnerQueryable.GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public Type ElementType
    {
        get { return _InnerQueryable.ElementType; }
    }

    public System.Linq.Expressions.Expression Expression
    {
        get { return _InnerQueryable.Expression; }
    }

    public IQueryProvider Provider
    {
        get { return _InnerQueryable.Provider; }
    }
}

Then you can use it like this:

var query = new QueryableWrapper<string>(
    from str in myDataSource
    select str);

Debug.WriteLine("HasExecuted: " + query.HasExecuted.ToString());

foreach (string str in query)
{
    Debug.WriteLine(str);
}

Debug.WriteLine("HasExecuted: " + query.HasExecuted.ToString());

Output is:

False
String0
String1
...
True

dcstraw
This seems as good of a solution as any. Hmmm ... maybe I could encapsulate this in an extension method so I can call iQueryable.Monitor() (or something like that). Interesting.
berko