Brandon Wenzel
Brandon Wenzel

Reputation: 445

How to set timeout for NHibernate LINQ statement

I am using Fluent NHibernate for my ORM. In doing so I am trying to use the NHibernate LINQ syntax to fetch a set of data with the power of LINQ. The code I have works and executes correctly with the exception being that a timeout is thrown if it takes longer than roughly 30 seconds to run. The question I have is how do I extend the default 30 second timeout for LINQ statements via NHibernate?

I have already seen the posts here, here, and here but the first two refer to setting the DataContext's Timeout property, which does not apply here, and the third refers to setting the timeout in XML, which also does not apply because I am using Fluent NHibernate to generate the XML on the fly. Not only that but the post is 2 years old and Fluent NHibernate has changed since.

With the ICriteria objects and even HQL I can specify the timeout, however that is not the goal here. I would like to know how to set that same timeout and use LINQ.

Example code:

    using (var session = SessionFactory.OpenSession())
    using (var transaction = session.BeginTransaction())
    {
        var query = (from mem in session.Query<Member>()
                     select mem);
        query = query.Where({where statement});
        int start = (currentPage - 1) * max);
        if (start > 0)
            query = query.Skip(start).Take(max);
        else
            query = query.Take(max);

        var list = query.ToList();
        transaction.Commit();
        return list;
    }

This code (where statement does not matter) works for all purposes except where a timeout occurs.

Any help is appreciated. Thanks in advance!

Upvotes: 13

Views: 12213

Answers (4)

Paul Gambke
Paul Gambke

Reputation: 21

Just in case anyone is still looking for this and finds this old thread too... Query.Timeout is deprecated. You should use WithOptions instead:

.WithOptions(o => o.SetTimeout(databaseTimeoutInSeconds))

Upvotes: 0

Daniel van Heerden
Daniel van Heerden

Reputation: 836

I've just spent fair amount of time fighting with this and hopefully this will save someone else some time.

You should use the .Timeout(120) method call at the very last moment to make sure it is used. TBH I'm not 100% sure on why this is but here are some examples:

WILL WORK

query = query.Where(x => x.Id = 123);

var result = query.Timeout(120).ToList();

DOESN'T WORK

query.Timeout(120);

query = query.Where(x => x.Id = 123);

var result = query.ToList();

If done like the second (DOESN'T WORK) example, it seems to fall back to the default System.Transaction.TransactionManager.DefaultTimeout.

Upvotes: 0

Brandon Wenzel
Brandon Wenzel

Reputation: 445

I ended up setting the command timeout for the Configuration for Fluent NHibernate. The downside to this is that it sets the timeout for ALL of my data access calls and not just the one.

Example code:

.ExposeConfiguration(c => c.SetProperty("command_timeout", (TimeSpan.FromMinutes(10).TotalSeconds).ToString()))

I found this suggestion from this website.

Upvotes: 13

Kingpin2k
Kingpin2k

Reputation: 47367

Nhibernate has extended the IQueryable and added a few methods https://github.com/nhibernate/nhibernate-core/blob/master/src/NHibernate/Linq/LinqExtensionMethods.cs

var query = (from c in Session.Query<Puppy>()).Timeout(12);

or

var query = (from c in Session.Query<Puppy>());

query.Timeout(456);

Upvotes: 9

Related Questions