При изменении LINQ-TO-SQL CommandText, должно быть закрыто соединение?
-
26-10-2019 - |
Вопрос
Я изменяю CommandText of Linq-to-SQL, чтобы заставить его использовать NoLock, как это ...
if (db.Connection.State == System.Data.ConnectionState.Closed)
db.Connection.Open();
var cmd = db.GetCommand(db.Customers.Where(p => p.ID == 1));
cmd.CommandText = cmd.CommandText.Replace("[Customers] AS [t0]", "[Customers] AS [t0] WITH (NOLOCK)");
var results = db.Translate(cmd.ExecuteReader());
Это приложение MVC, поэтому DataContext находится в базовом контроллере и, возможно, использовался до этого кода, и, что более важно, после. Должен ли я закрыть соединение в этой рутине? Или вообще нет? Или только если я открыл его здесь?
Обновлять:
Сейчас я использую более общую функцию (в классе DataContext) для изменения CommandText и закрытия соединения, если оно было открыто здесь. И открытие было перенесено к исполнителю. До сих пор он работал и уменьшал спорадические проблемы тупика. Результаты не обязательно должны быть вверх на секунду.
public List<T> GetWithNolock<T>(IQueryable<T> query)
{
// to skip nolock, just...
// return query.ToList();
List<T> results = null;
bool opened = false;
try
{
if (Connection.State == System.Data.ConnectionState.Closed)
{
Connection.Open();
opened = true;
}
using (var cmd = GetCommand(query))
{
cmd.CommandText = Regex.Replace(cmd.CommandText, @"((from|inner join) \[dbo.*as \[t\d+\])", "$1 with (nolock)", RegexOptions.IgnoreCase);
results = Translate<T>(cmd.ExecuteReader()).ToList();
}
}
finally
{
if (opened && Connection.State == System.Data.ConnectionState.Open)
{
Connection.Close();
}
}
return results;
}
В прошлом я обнаружил, что использование транзакции рекомендуется приводит к тому, что сайт не заканчивает соединения в течение ночи. Насколько я знаю, это ошибка в Linq-to-Sql. Могут быть способы обойти это, но я стараюсь сохранить свой основной код простым. Теперь я «просто» должен сделать это ...
var users = GetWithNolock<User>(
Users
.Where(u => my query
);
Решение
Если вы откроете его, вы должны закрыть его. Другие операции LinqtoSQL соответствуют этому шаблону.
В своем коде я безоговорочно открываю соединение и наконец закрываю соединение. Если кто -то передает мне открытое соединение, это их вина, и я случайно закрыл ее для них.
Вы можете отложить открытие подключения до тех пор, пока не исполняют исполнитель.