Диалект / Драйвер - Каждый SELECT, который я выполняю, добавляет с - PullRequest
0 голосов
/ 30 марта 2012

Мне нужно знать способ реализации в моей системе драйвера или диалекта, который всякий раз, когда я выполняю SELECT в Nhibernate, SELECT добавляет с ним (nolock). Мне нужно, чтобы это было в C # и NHibernate, а не напрямую в БД!

Надеюсь, вы понимаете!

Спасибо!

Ответы [ 4 ]

2 голосов
/ 30 марта 2012

Можно изменить sql, используя Interceptor и переопределяя метод 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 голосов
/ 30 марта 2012

Использование подсказки WITH(NOLOCK) аналогично использованию уровня изоляции транзакции READ UNCOMMITED, как описано здесь: Когда следует использовать «with (nolock)» .

Вы можете указать уровень изоляции транзакции при запуске новых транзакций с помощью NHibernate:

var session = SessionFactory.OpenSession();
session.BeginTransaction(IsolationLevel.ReadUncommitted);

Я бы не рекомендовал это, если вы действительно не знаете, что делаете. Вот еще немного информации по этому вопросу: Зачем использовать уровень изоляции READ UNCOMMITTED? .

1 голос
/ 22 августа 2013

Надеюсь, это кому-нибудь поможет, Я использовал этот код, чтобы не добавлять подсказок блокировки к большинству запросов, связанных с ответом 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;
        }
    }
0 голосов
/ 12 сентября 2016

В этом коде есть две ошибки:

  1. Для сценария SQL с параметром Этот код не будет работать.
  2. SqlString.Parts не компилируется, я использую NHibernate 4.0.0.4000

Вот исправление:


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;
        }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...