我正在修改 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 类中)来修改命令文本,并在此处打开连接时关闭连接。并且 open 已下移至 ExecuteReader。到目前为止,它一直在工作并减少零星的僵局问题。结果不必精确到秒。
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
);