Как я могу использовать NOLOCK с LINQ? [Дубликат]

Вот простое решение:

String content;

content = new String(Files.readAllBytes(Paths.get("sample.txt")));
62
задан ThinkingStiff 18 January 2012 в 22:42
поделиться

5 ответов

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

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

Оказывается, вы можете сделать всю транзакцию «прочитайте незафиксированную», используя старое пространство имен 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 to SQL и LINQ to Entities

Matt Hamilton - LINQ to SQL и NOLOCK Советы: Mad Props!

Скотч Hanselman's Computer Zen - Получение LINQ to SQL и LINQ to ...

77
ответ дан Eric 17 August 2018 в 14:49
поделиться
  • 1
    Если бы я хотел быть абсолютно правильным, ни один из этих вариантов фактически не выдавал NOLOCK & quot; в самом SQL - вместо этого они используют настройку изоляции транзакции. То же самое, но не технически, что задал вопрос. – Matt Hamilton 3 August 2009 в 06:56
  • 2
    Скопировал текст из своего блога, так что никто не должен переходить по ссылкам, чтобы получить ответ. – Eric 3 August 2009 в 07:06
  • 3
    @Matt: Вот в чем дело! Создайте канонический источник! См. meta.stackexchange.com/questions/8724/… – Eric 3 August 2009 в 07:21
  • 4
    Придется согласиться с Мэттом по воровству контента. Мэтт нашел время, чтобы написать сообщение в своем блоге. Теперь DOG получает трафик – Andrew Harry 18 December 2009 в 15:36
  • 5
    Вы не можете повышать и понижать ответы в блоге, и поэтому нет возможности проверить качество там. Я думаю, что копирование коротких фрагментов к SO с атрибуцией - правильный путь. – Kirk Woll 21 June 2011 в 16:20

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

private FoobarEntities db = new FoobarEntities();
public FoobarController()
{
    db.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");
}
2
ответ дан Akira Yamamoto 17 August 2018 в 14:49
поделиться
  • 1
    Спасибо, ваше решение избегает & quot; COMException: диспетчер транзакций отключил поддержку удаленных / сетевых транзакций. & Quot; которые могут добавляться по другим запросам. – Olivier de Rivoyre 27 June 2017 в 08:16

В дополнение к дополнению LinqPad My ExtensionsKing 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().

17
ответ дан Community 17 August 2018 в 14:49
поделиться
  • 1
    Это можно немного подобрать, добавив статический метод GetReadUncommittedScope(), а затем выполнив using (var txn = GetReadUncommittedScope()) – asherber 5 January 2017 в 21:48
  • 2
    @asherber Сделано. – Mark Hurd 6 January 2017 в 02:25

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

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

  // Your SQL query
}
10
ответ дан Soppus 17 August 2018 в 14:49
поделиться
  • 1
    Возможно, этот ответ, встроенный в ответ на вопросы, будет приятным – Pierre 12 October 2014 в 11:56

Ниже приведен метод расширения для использования с 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();
7
ответ дан theKing 17 August 2018 в 14:49
поделиться
  • 1
    Это действительно приятное решение. Чисто и просто! – Colin 31 October 2012 в 01:36
Другие вопросы по тегам:

Похожие вопросы: