Как использовать функцию NOLOCK в Entity Framework? Является ли XML единственным способом сделать это?Entity Framework с NOLOCK
ответ
Нет, но вы можете начать транзакцию и установить isolation level to read uncommited. Это по сути делает то же самое, что и NOLOCK, но вместо того, чтобы делать это на основе таблицы, он будет делать это для всего, что входит в объем транзакции.
Если это звучит как то, что вы хотите, вот, как вы могли бы пойти делать это ...
//declare the transaction options
var transactionOptions = new System.Transactions.TransactionOptions();
//set it to read uncommited
transactionOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted;
//create the transaction scope, passing our options in
using (var transactionScope = new System.Transactions.TransactionScope(
System.Transactions.TransactionScopeOption.Required,
transactionOptions)
)
//declare our context
using (var context = new MyEntityConnection())
{
//any reads we do here will also read uncomitted data
//...
//...
//don't forget to complete the transaction scope
transactionScope.Complete();
}
Нет, на самом деле - структура Entity Framework в основном довольно строгий уровень над вашей фактической базой данных. Ваши запросы сформулированы в ESQL - Entity SQL, который в первую очередь нацелен на вашу модель сущности, и поскольку EF поддерживает несколько баз данных, вы действительно не можете отправлять «родной» SQL непосредственно на ваш сервер.
Подсказка запроса NOLOCK является специфической вещью SQL Server и не будет работать ни на одной из других поддерживаемых баз данных (кроме случаев, когда они также реализовали один и тот же намек, на что я очень сомневаюсь).
Марк
Этот ответ устарел - вы можете использовать NOLOCK, как упомянули другие, и вы можете выполнить «собственный» SQL, используя 'Database.ExecuteSqlCommand()' или 'DbSet
@ Dunc: спасибо за downvote - btw: вы должны *** НЕ использовать *** (NOLOCK) 'в любом случае - см. [Bad Habits to kick - put NOLOCK везде] (http://blogs.sqlsentry.com/ aaronbertrand/bad-habits-nolock-везде /) - это НЕ РЕКОМЕНДУЕТСЯ *** использовать это везде - совсем наоборот! –
Добро пожаловать. – Dunc
Чтобы обойти это я создать представление в базе данных и применять NOLOCK по запросу представления. Затем я рассматриваю представление как таблицу в EF.
Если вам нужно что-то в целом, лучший способ, который мы обнаружили, который менее навязчив, чем запуск транзакции каждый раз, заключается в том, чтобы просто установить уровень изоляции транзакций по умолчанию в вашем соединении после создания контекста объекта, выполнив это простая команда:
this.context.ExecuteStoreCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");
http://msdn.microsoft.com/en-us/library/aa259216(v=sql.80).aspx
с помощью этого метода, мы смогли создать простой поставщика EF, который создает контекст для нас, и на самом деле работает эту команду каждый раз, когда для всех наших условий, с тем, что мы» re всегда в "read uncommitted" по умолчанию.
Установка уровня изоляции транзакции не будет иметь никакого эффекта , Вам действительно нужно работать в транзакции, чтобы она имела какой-либо эффект. Документация MSDN для READ UNCOMMITTED утверждает, что транзакции, выполняемые на уровне READ UNCOMMITTED, не выдают совместно используемые блокировки. Это означает, что вы должны работать в рамках транзакции, чтобы получить выгоду. (взято из http://msdn.microsoft.com/en-gb/library/ms173763.aspx). Ваш подход может быть менее навязчивым, но он ничего не добьется, если вы не используете транзакцию. –
Документация MSDN гласит: «Управляет управлением версиями Transact-SQL, связанными с блокировкой и строкой, выдаваемыми при подключении к SQL Server». и «Указывает, что операторы могут читать строки, которые были изменены другими транзакциями, но еще не выполнены». Это заявление, которое я написал, затрагивает все инструкции SQL, которое находится внутри транзакции или нет. Мне не нравится противоречить людям в Интернете, но вы явно ошибаетесь в этом, основываясь на нашем использовании этого заявления в большой производственной среде. Не думай о вещах, ПОПРОБУЙТЕ ИХ! –
Я пробовал их, у нас есть среда с высокой нагрузкой, где не выполнение запросов в одной из этих областей транзакций (и соответствующей транзакции) приведет к тупиковой ситуации. Мои наблюдения были сделаны на сервере SQL 2005, поэтому я не знаю, изменилось ли поведение с тех пор. Поэтому я рекомендую это; если вы укажете уровень незанятой изоляции, но продолжаете испытывать взаимоблокировки, попробуйте поместить свои запросы в транзакцию. Если вы не столкнетесь с взаимоблокировками, не создавая транзакцию, то достаточно справедливы. –
метода расширения может сделать это проще
public static List<T> ToListReadUncommitted<T>(this IQueryable<T> query)
{
using (var scope = new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions() {
IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted }))
{
List<T> toReturn = query.ToList();
scope.Complete();
return toReturn;
}
}
public static int CountReadUncommitted<T>(this IQueryable<T> query)
{
using (var scope = new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions() {
IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted }))
{
int toReturn = query.Count();
scope.Complete();
return toReturn;
}
}
Хорошая работа, мне нравится это решение. –
Человек я люблю методы расширения. Это потрясающе! –
Использование этого в моем проекте приводит к тому, что пул соединений полностью используется, что приводит к исключению. не может понять, почему. У кого-нибудь еще есть проблемы? Какие-либо предложения? –
Хотя я абсолютно согласился, что использование Read Uncommitted уровня изоляции транзакций является лучшим выбором, но через некоторое время вы вынуждены использовать NOLOCK подсказку по требованию менеджера или клиента и нет причины против этого приняты.
С Entity Framework 6 вы можете реализовать собственный DbCommandInterceptor как это:
С помощью этого класса на месте, вы можете применить его при запуске приложения:
DbInterception.Add(new NoLockInterceptor());
И условно отключить добавление NOLOCK
намек на запросы для текущей резьбы:
NoLockInterceptor.SuppressNoLock = true;
Мне нравится это решение, хотя я немного изменил регулярное выражение: – Russ
(?
Настройка SuppressNoLock на уровне потока - это удобный способ, но легко забыть отменить логическое значение, вы должны использовать функцию, возвращающую IDisposable, метод Dispose может просто снова установить bool в false. Также ThreadStatic на самом деле не совместим с async/await: http://stackoverflow.com/questions/13010563/using-threadstatic-variables-with-async-await – Jaap
Усовершенствование на принятом Doctor Jones и использование PostSharp;
Первый «ReadUncommitedTransactionScopeAttribute»
[Serializable]
public class ReadUncommitedTransactionScopeAttribute : MethodInterceptionAspect
{
public override void OnInvoke(MethodInterceptionArgs args)
{
//declare the transaction options
var transactionOptions = new TransactionOptions();
//set it to read uncommited
transactionOptions.IsolationLevel = IsolationLevel.ReadUncommitted;
//create the transaction scope, passing our options in
using (var transactionScope = new TransactionScope(TransactionScopeOption.Required, transactionOptions))
{
//declare our context
using (var scope = new TransactionScope())
{
args.Proceed();
scope.Complete();
}
}
}
}
Тогда всякий раз, когда вам это нужно,
[ReadUncommitedTransactionScope()]
public static SomeEntities[] GetSomeEntities()
{
using (var context = new MyEntityConnection())
{
//any reads we do here will also read uncomitted data
//...
//...
}
}
Будучи в состоянии добавить «NOLOCK» с перехватчик также хорошо, но не будет работать при подключении к другие системы баз данных, такие как Oracle как таковые.
Один из вариантов заключается в использовании хранимой процедуры (аналогично решению вида, предложенной Райаном), а затем выполнить хранимую процедуру из EF. Таким образом, хранимая процедура выполняет грязное чтение, а EF просто передает результаты.
- 1. NoLock в Entity Framework
- 2. Entity Framework присоединяется к NOLOCK
- 3. Почему Entity Framework игнорирует TransactionScope (не добавляя с помощью NOLOCK)?
- 4. с (nolock), (nolock), nolock отличия?
- 5. DI с Entity Framework Entity
- 6. Entity constructors - Entity framework
- 7. GetWeekOfYear с Entity Framework
- 8. Entity Framework с ROWGUIDCOL
- 9. Entity Framework с SQLite
- 10. Downcasting с Entity Framework
- 11. выборки с Entity Framework
- 12. Потокобезопасность с Entity Framework
- 13. автореферентное с Entity Framework
- 14. Entity Framework с MySQL
- 15. Проблема с Entity Framework
- 16. Entity Framework с Oracle
- 17. Entity Framework + Unity Framework
- 18. Entity Framework Update Entity
- 19. Сопоставление POCO с Entity Framework в Entity Framework
- 20. Entity Framework
- 21. Entity Framework с mysql, entity без PK
- 22. entity framework
- 23. Entity Framework
- 24. NOLOCK с многопоточным
- 25. Entity Framework - unmapped entity. Возможное?
- 26. Linq To Entity Framework выбрать целые таблицы
- 27. Entity Framework 4.0. Создание Entity
- 28. Entity Framework Update Navigation Entity
- 29. Entity Framework, вычисляемое поле Entity
- 30. Связь с картой Entity Framework
Excellent @DoctaJonez Было ли что-то новое в EF4 для этого? – FMFF
@FMFF Я не знаю, было ли что-то новое для EF4. Я знаю, что приведенный выше код работает с EFv1 и выше. –
что было бы последствием? если кто-то опустил транзакциюScope.Complete() в упомянутом выше блоке? Как вы думаете, я должен задать еще один вопрос? –