我在MVC 5项目中使用Entity Framework 6.如您所知,SELECT如果我们使用SQL Server中的查询,它们的执行速度更快,效率更高WITH (NOLOCK).我查看了Entity Framework 6生成的一些SQL SELECT语句,并意识到它们都不包含NOLOCK.
我不想在我的提取操作中使用事务来读取未提交的事务.
如何在下面生成的SELECT语句中强制使用EF 6来使用NOLOCK?
使用C#中的新async/await关键字,现在会对使用ThreadStatic数据的方式(以及何时)产生影响,因为回调委托在与async启动的操作不同的线程上执行.例如,以下简单的控制台应用程序:
[ThreadStatic]
private static string Secret;
static void Main(string[] args)
{
Start().Wait();
Console.ReadKey();
}
private static async Task Start()
{
Secret = "moo moo";
Console.WriteLine("Started on thread [{0}]", Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("Secret is [{0}]", Secret);
await Sleepy();
Console.WriteLine("Finished on thread [{0}]", Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("Secret is [{0}]", Secret);
}
private static async Task Sleepy()
{
Console.WriteLine("Was on thread [{0}]", Thread.CurrentThread.ManagedThreadId);
await Task.Delay(1000);
Console.WriteLine("Now on thread [{0}]", Thread.CurrentThread.ManagedThreadId);
}
Run Code Online (Sandbox Code Playgroud)
将输出以下内容:
Started on thread [9]
Secret is [moo moo]
Was on thread [9]
Now …Run Code Online (Sandbox Code Playgroud) 使用"SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED"和NOLOCK之间有什么区别?这个比那个好吗?
可能重复:
使用NOLOCK的实体框架
我正在使用EF4和.Net 4将一些XML从文件加载到数据库中.
我有一个包围ObjectContext的类,并且有一些方法可以将XML文件中的编组对象添加到代表我的表的各种EntityCollections中.
每个XML文件平均包含大约200,000个对象,包装类在构造时创建ObjectContext并将引用存储在本地私有类变量中,然后由方法使用.
当我完成创建我打电话的实体时:
entities.SaveChanges(SaveOptions.AcceptAllChangesAfterSave);
Run Code Online (Sandbox Code Playgroud)
这将在服务器上创建一个事务,该事务按照EntityFramework设计.但是,即使在未添加到的表上,此事务也完全锁定了我的数据库.
我尝试了各种各样的事情来解决这个问题,包括在TransactionScope中包装保存更改,如下所示:
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Suppress,
new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted }))
{
entities.SaveChanges(SaveOptions.AcceptAllChangesAfterSave);
transaction.Complete();
}
Run Code Online (Sandbox Code Playgroud)
我还尝试在创建ObjectContext之前创建TransactionScope,以试图影响在SaveChanges期间使用的基础事务.
理想情况下,我希望一次加载多个文件,但如果在保存更改期间锁定了DB,则无法进行此操作.
有谁知道解决这个问题的方法?有没有强制EntityFramework不使用事务?
在此先感谢您的帮助.
詹姆士
我有一个OData服务(使用实体框架的WCF数据服务).
所有这些服务都是选择数据.(没有写过.)
当我运行我的OData查询时,我偶尔会收到这样的错误:
事务(进程ID 95)在锁资源上与另一个进程死锁,并被选为死锁牺牲品.重新运行该交易
select语句可以成为死锁受害者吗?或者是实体框架试图锁定不应该锁定的东西?
如果它锁定在它不应该的位置,是否有办法告诉实体框架永远不会锁定?(对于这项服务,它总是永远是只读的.)
c# entity-framework entity-framework-4 wcf-data-services odata
因此,我有带有EF和SQL Server 2008的MVC应用程序,并且它与另一个经常写入一些数据的应用程序共享数据库。MVC应用程序会基于来自另一个应用程序的数据生成一些实时报告。
因此,考虑到这种情况,是否有可能在生成报告时阻止某些应用程序试图写入数据的表?
我尝试在生成报表时进行一些手动插入和更新,并且处理起来还不错。我误会了吗?
我试图在EntityFramework Core 2.0的SELECT查询中使用TransactionScope.但是我收到此错误:"不支持在Ambient事务中登记."
当我选择查询时,我们的想法是实现"NO LOCK"选项(我知道这个选项不是一个好主意,但它是供应商的要求).所以我添加了一个扩展方法(带有NOLOCK的实体框架)
public static async Task<List<T>> ToListReadUncommittedAsync<T>(this IQueryable<T> query)
{
using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew,
new TransactionOptions()
{
IsolationLevel = IsolationLevel.ReadUncommitted
}, TransactionScopeAsyncFlowOption.Enabled))
{
var result = await query.ToListAsync();
scope.Complete();
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
而且我也设置忽略环境交易警告.
public static void AddEntityFramework(this IServiceCollection services, string connectionString)
{
services.AddDbContextPool<OptomateContext>(options =>
{
options.UseSqlServer(connectionString);
options.ConfigureWarnings(x => x.Ignore(RelationalEventId.AmbientTransactionWarning));
});
}
Run Code Online (Sandbox Code Playgroud)
我在我的存储库中有如下查询
public async Task<Patient> GetPatient(Common.Resources.Patient patient)
{
var pat = await Dbset.Where(x => string.Equals(x.Surname,patient.Surname,
StringComparison.CurrentCultureIgnoreCase)).ToListReadUncommittedAsync();
return pat.FirstOrDefault();
}
Run Code Online (Sandbox Code Playgroud)
我明白.Net Core …
c# entity-framework transactionscope entity-framework-core ef-core-2.0
我错过了什么?
我正在尝试使用像这样的TransactionScope读取NOLOCK:
var scopeOptions = new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted };
using (var scope = new TransactionScope(TransactionScopeOption.Required, scopeOptions))
{
using (var db = new MyDbContext(ConnectionStringEntities))
{
// Simple read with a try catch block...
}
scope.Complete();
}
Run Code Online (Sandbox Code Playgroud)
我希望看到NOLOCK添加到SQL查询中(查看SQL Profiler以及自定义DbCommandInterceptor - 但它不存在...
更新:经过一些更多的研究,我想知道所选的光标是否正在被使用,只是没有NOLOCK"提示"(特定于SQL Server - 并且还特定于一个表),我找到了一些代码来获取当前事务和它似乎显示正确选择的事务隔离(ReadUncommitted/Serializable等)我仍然想测试它,但如果你有任何想法让我知道
获取当前的.net TransactionScope IsolationLevel
Transaction trans = Transaction.Current;
System.Transactions.IsolationLevel level = trans.IsolationLevel;
LogService.Instance.Debug($"Transaction IsolationLevel = {level.ToString()}");
Run Code Online (Sandbox Code Playgroud) 我有针对SQL Server 2008的实体框架(.NET 4.0).数据库(理论上)在工作时间内更新 - 删除,然后插入,全部通过事务.实际上,它不会经常发生.但是,我需要确保我始终可以读取数据库中的数据.我正在编写的应用程序永远不会对数据进行任何类型的写入 - 只读.
如果我进行脏读,我总能访问数据; 发生的最糟糕的事情是我得到旧数据(这是可以接受的).但是,我可以告诉Entity Framework始终使用脏读吗?如果我以这种方式设置EF,是否需要担心性能或数据完整性问题?或者我应该退一步看看重写正在执行删除/插入过程的过程?
sql-server ×5
c# ×4
sql ×3
.net ×1
async-await ×1
blocking ×1
ef-core-2.0 ×1
nolock ×1
odata ×1
performance ×1
query-hints ×1
transactions ×1