NOLOCK с Linq to SQL - PullRequest
       26

NOLOCK с Linq to SQL

68 голосов
/ 03 августа 2009

Можно ли заставить Linq2Sql выдавать NOLOCK в его SQL? И если да, то как?

Ответы [ 5 ]

83 голосов
/ 03 августа 2009

Да, это так, вот запись из моего блога :

Подсказка NOLOCK по сути так же, как упаковка запроса в транзакция, чей «уровень изоляции» установить "читать незафиксированные". Это значит что запрос не волнует, если вещи находится в процессе написания строки, из которых он читает - это будет прочитать эти «грязные» данные и вернуть их как часть набора результатов.

Оказывается, вы можете сделать все «прочесть незафиксированную» транзакцию используя старую System.Transactions пространство имен, представленное в .NET 2.0. Вот пример кода:

using (var txn = new TransactionScope(
    TransactionScopeOption.Required, 
    new TransactionOptions
    {
        IsolationLevel = IsolationLevel.ReadUncommitted
    }
))
{
    // Your LINQ to SQL query goes here
}

Итак, я создаю новый TransactionScope объект и говорит ему использовать уровень изоляции без чтения. запрос внутри оператора "using" сейчас действует так, как будто все его таблицы читают с подсказкой NOLOCK.

Вот первые результаты поиска Google "linq sql nolock":

InfoQ: Реализация NOLOCK с LINQ для SQL и LINQ для сущностей

Мэтт Гамильтон - LINQ to SQL и NOLOCK Подсказки: Mad Props!

Компьютер Дзэн Скотта Хансельмана - Получение LINQ to SQL и LINQ to ...

21 голосов
/ 31 октября 2014

В дополнение к королю LinqPad My Extensions дополнение :

public static IQueryable<T> DumpNoLock<T>(this IQueryable<T> query)
{
    using (var txn = GetNewReadUncommittedScope())
    {
        return query.Dump();
    }   
}

public static System.Transactions.TransactionScope GetNewReadUncommittedScope()
{
    return new System.Transactions.TransactionScope(
        System.Transactions.TransactionScopeOption.RequiresNew,
        new System.Transactions.TransactionOptions
        {
            IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted
        });
}
public static IQueryable<T> DumpNoLock<T>(this IQueryable<T> query, string description)
{
    using (var txn = GetNewReadUncommittedScope())
    {
        return query.Dump(description);
    }   
}

public static List<T> ToListNoLock<T>(this IQueryable<T> query)
{
    using (var txn = GetNewReadUncommittedScope())
    {
        return query.ToList();
    }   
}

public static U NoLock<T,U>(this IQueryable<T> query, Func<IQueryable<T>,U> expr)
{
    using (var txn = GetNewReadUncommittedScope())
    {
        return expr(query);
    }   
}

Последнее означает, что вы можете выполнить NOLOCK для любых оценочных запросов, для которых у вас нет явно написанного NoLock (как у меня для ToListNoLock выше). Так, например:

somequery.NoLock((x)=>x.Count()).Dump();

оценит запрос с помощью NOLOCK.

Обратите внимание, что вы должны убедиться, что оцениваете запрос. Например. .NoLock((x)=>x.Distinct()).Count().Dump() не сделает ничего полезного, отличного от .Distinct().Count().Dump().

11 голосов
/ 04 октября 2013

Простым способом может быть запуск команды в вашем классе DataContext

using (var dataContext = new DataContext())
{
  dataContext.ExecuteCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");

  // Your SQL query
}
8 голосов
/ 09 августа 2012

Вот метод расширения для использования с LINQPAD

    public static IQueryable<T> Dump2<T>(this IQueryable<T> query)
{
    using (var txn = new System.Transactions.TransactionScope(TransactionScopeOption.RequiresNew, 
        new TransactionOptions
        {       
            IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted
        }))
    {
        return query.Dump();
    }   
}

Тогда вы можете назвать это как:

MyTable.Where(t => t.Title = "Blah").Dump2();
2 голосов
/ 18 марта 2014

В моем случае Entity Framework 5 (на основе ответа @Soppus):

private FoobarEntities db = new FoobarEntities();
public FoobarController()
{
    db.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...