Как установить тайм-аут для оператора NHibernate LINQ
Я использую Fluent NHibernate для своего ORM. При этом я пытаюсь использовать синтаксис NHibernate LINQ для извлечения набора данных с помощью LINQ. Код, который у меня есть, работает и выполняется правильно, за исключением того, что выдается тайм-аут, если для выполнения требуется более 30 секунд. Вопрос, который у меня есть, заключается в том, как продлить 30-секундный тайм-аут по умолчанию для операторов LINQ через NHibernate?
Я уже видел сообщения здесь, здесь и здесь, но первые два относятся к установке свойства TimeContext Timeout, которое здесь не применяется, а третий относится к установке таймаута в XML, что также не применяется, поскольку я использую Fluent NHibernate для создания XML на лету. Не только это, но и пост 2 года, и Fluent NHibernate изменился с тех пор.
С объектами ICriteria и даже с HQL я могу указать время ожидания, однако это не цель. Я хотел бы знать, как установить тот же тайм-аут и использовать LINQ.
Пример кода:
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;
}
Этот код (где оператор не имеет значения) работает для всех целей, кроме случаев, когда происходит таймаут.
Любая помощь приветствуется. Спасибо заранее!
Ответы
Ответ 1
Nhibernate расширил IQueryable и добавил несколько методов https://github.com/nhibernate/nhibernate-core/blob/master/src/NHibernate/Linq/LinqExtensionMethods.cs
var query = (from c in Session.Query<Puppy>()).Timeout(12);
или
var query = (from c in Session.Query<Puppy>());
query.Timeout(456);
Ответ 2
Я закончил установку таймаута команды для конфигурации для свободного NHibernate. Недостатком этого является то, что он устанавливает тайм-аут для ВСЕХ моих вызовов доступа к данным, а не только одного.
Пример кода:
.ExposeConfiguration(c => c.SetProperty("command_timeout", (TimeSpan.FromMinutes(10).TotalSeconds).ToString()))
Я нашел это предложение от этого веб-сайта.
Ответ 3
Я потратил немало времени на борьбу с этим, и, надеюсь, это немного сэкономит время.
Вы должны использовать вызов метода .Timeout(120)
в самый последний момент, чтобы убедиться, что он используется. TBH Я не уверен на 100%, почему это так, но вот несколько примеров:
РАБОТАЕТ
query = query.Where(x => x.Id = 123);
var result = query.Timeout(120).ToList();
НЕ РАБОТАЕТ
query.Timeout(120);
query = query.Where(x => x.Id = 123);
var result = query.ToList();
Если сделать это как второй пример (НЕ РАБОТАЕТ), он, похоже, возвращается к умолчанию System.Transaction.TransactionManager.DefaultTimeout.