我需要知道一种在我的系统中实现的方法,一个Driver或Dialect,每当我在Nhibernate中执行SELECT时,SELECT都会添加with(nolock)。 我需要它在C#和NHibernate中,而不是直接在DB中!
希望你能理解!
谢谢!
答案 0 :(得分:2)
使用WITH(NOLOCK
)提示与使用READ UNCOMMITED事务隔离级别相同,如下所述:When should you use "with (nolock)"。
使用NHibernate启动新事务时,可以指定事务隔离级别:
var session = SessionFactory.OpenSession();
session.BeginTransaction(IsolationLevel.ReadUncommitted);
除非你真的知道自己在做什么,否则我不会推荐这个。以下是有关该主题的更多信息:Why use a READ UNCOMMITTED isolation level?。
答案 1 :(得分:2)
可以使用Interceptor修改sql并覆盖OnPrepareStatement
方法,如下所示:
public class AddNoLockHintsInterceptor : EmptyInterceptor
{
public override SqlString OnPrepareStatement(SqlString sql)
{
// Modify the sql to add hints
return sql;
}
}
这是一种用NHibernate注册拦截器的方法:
var session = SessionFactory.OpenSession(new AddNoLockHintsInterceptor());
答案 2 :(得分:1)
希望这会对某人有所帮助, 我使用此代码为大多数查询添加了没有锁定提示,与答案dillenmeister相关
public class NoLockHintsInterceptor : EmptyInterceptor
{
public override SqlString OnPrepareStatement(SqlString sql)
{
// Modify the sql to add hints
if (sql.StartsWithCaseInsensitive("select"))
{
var parts = new List<object>((object[]) sql.Parts);
object fromItem = parts.FirstOrDefault(p => p.ToString().ToLower().Trim().Equals("from"));
int fromIndex = fromItem != null ? parts.IndexOf(fromItem) : -1;
object whereItem = parts.FirstOrDefault(p => p.ToString().ToLower().Trim().Equals("where"));
int whereIndex = whereItem != null ? parts.IndexOf(whereItem) : parts.Count;
if (fromIndex == -1)
return sql;
parts.Insert(parts.IndexOf(fromItem) + 2, " with(nolock) ");
for (int i = fromIndex; i < whereIndex; i++)
{
if (parts[i - 1].Equals(","))
{
parts.Insert(i + 2, " with(nolock) ");
i += 2;
}
if (parts[i].ToString().Trim().EndsWith(" on"))
{
parts[i] = parts[i].ToString().Replace(" on", " with(nolock) on ");
}
}
sql = new SqlString(parts.ToArray());
}
return sql;
}
}
答案 3 :(得分:0)
此代码中有两个错误:
以下是修复:
public class NoLockInterceptor : EmptyInterceptor
{
public override SqlString OnPrepareStatement(SqlString sql)
{
//var log = new StringBuilder();
//log.Append(sql.ToString());
//log.AppendLine();
// Modify the sql to add hints
if (sql.StartsWithCaseInsensitive("select"))
{
var parts = sql.ToString().Split().ToList();
var fromItem = parts.FirstOrDefault(p => p.Trim().Equals("from", StringComparison.OrdinalIgnoreCase));
int fromIndex = fromItem != null ? parts.IndexOf(fromItem) : -1;
var whereItem = parts.FirstOrDefault(p => p.Trim().Equals("where", StringComparison.OrdinalIgnoreCase));
int whereIndex = whereItem != null ? parts.IndexOf(whereItem) : parts.Count;
if (fromIndex == -1)
return sql;
parts.Insert(parts.IndexOf(fromItem) + 3, "WITH (NOLOCK)");
for (int i = fromIndex; i < whereIndex; i++)
{
if (parts[i - 1].Equals(","))
{
parts.Insert(i + 3, "WITH (NOLOCK)");
i += 3;
}
if (parts[i].Trim().Equals("on", StringComparison.OrdinalIgnoreCase))
{
parts[i] = "WITH (NOLOCK) on";
}
}
// MUST use SqlString.Parse() method instead of new SqlString()
sql = SqlString.Parse(string.Join(" ", parts));
}
//log.Append(sql);
return sql;
}
}