Ответ 1
Похоже, вы нашли ошибку в EF, но когда вы сообщаете об этом в MS, это будет считаться ошибкой в документации. В любом случае мне не нравится идея напрямую взаимодействовать с EntityCommand
. Вот мой пример, как убить текущий запрос:
var thread = new Thread((param) =>
{
var currentString = param as string;
if (currentString == null)
{
// TODO OMG exception
throw new Exception();
}
AdventureWorks2008R2Entities entities = null;
try // Don't use using because it can cause race condition
{
entities = new AdventureWorks2008R2Entities();
ObjectQuery<Person> query = entities.People
.Include("Password")
.Include("PersonPhone")
.Include("EmailAddress")
.Include("BusinessEntity")
.Include("BusinessEntityContact");
// Improves performance of readonly query where
// objects do not have to be tracked by context
// Edit: But it doesn't work for this query because of includes
// query.MergeOption = MergeOption.NoTracking;
foreach (var record in query
.Where(p => p.LastName.StartsWith(currentString)))
{
// TODO fill some buffer and invoke UI update
}
}
finally
{
if (entities != null)
{
entities.Dispose();
}
}
});
thread.Start("P");
// Just for test
Thread.Sleep(500);
thread.Abort();
Это результат моей игры, если через 30 минут это, вероятно, не является чем-то, что следует считать окончательным решением. Я отправляю его, по крайней мере, получаю некоторую обратную связь с возможными проблемами, вызванными этим решением. Основные пункты:
- Контекст обрабатывается внутри потока
- Результат не отслеживается контекстом
- Если вы убиваете запрос потока, завершается, и контекст располагается (соединение освобождено)
- Если вы закроете поток перед тем, как начать новый поток, вы должны использовать еще одно соединение.
Я проверил, что запрос запущен и завершен в профилировщике SQL.
Edit:
Btw. другой подход просто остановить текущий запрос находится внутри перечисления:
public IEnumerable<T> ExecuteQuery<T>(IQueryable<T> query)
{
foreach (T record in query)
{
// Handle stop condition somehow
if (ShouldStop())
{
// Once you close enumerator, query is terminated
yield break;
}
yield return record;
}
}