EF6读取未提交的数据

时间:2017-08-24 17:00:51

标签: c# sql-server-2012 entity-framework-6

我需要执行如下的交易:

  1. 开始交易:我在这里致电context.Database.BeginTransaction()(请注意context这里的问题不同于我想要读取的未提交的问题。
  2. 保存联系人(使用存储过程完成):此usp也有一个事务。
  3. 根据联系人(使用EF应用程序端完成)创建一些其他记录
  4. 提交
  5. 我遇到的问题是,在第3步中,我需要从尚未提交的数据库中读取一些数据(从步骤2开始)。我尝试过这样做,但它无法正常工作:

    context.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");
    var contact = context.Contact.SingleOrDefault(x => x.ContactId == intId);
    context.Database.ExecuteSqlCommand("SET TRANSACTION ISOLATION LEVEL READ COMMITTED;");
    

    我让调试器运行并在提取contact的位置暂停,但没有返回任何内容。

    如果我在SSMS(sql server mgmt studio)中查询相同的记录,则返回结果:

    set transaction isolation level read uncommitted
    select * from Contact c where c.ContactId = 9999
    

    问题

    1. 如何使用EF6读取未提交的数据?一些在线搜索引导我创建一个自定义拦截器,但我真的需要吗?
    2. 许多文章建议不要阅读未提交的数据,但我想不出另一种方法来实现这一点。有吗?

2 个答案:

答案 0 :(得分:0)

您可以尝试在TransactionScope中包装数据库访问代码,如下所示:

using (var scope = new TransactionScope(TransactionScopeOption.Required,
                new TransactionOptions() { IsolationLevel = IsolationLevel.ReadUncommitted }))

您是如何开始交易的?我问,因为如果代码流如您所述,步骤2和3中的所有操作都应该在同一个事务中完成,并且该事务应该能够看到先前操作在同一事务中所做的任何更改。

您也可以尝试使用SQL Server Profiler观察数据库交互,并查看是否正在创建其他(新)事务。

如果您发布了执行步骤1到步骤4的实际代码,则可能会有所帮助。

答案 1 :(得分:0)

我知道这个问题有些陈旧,但只是希望它能为其他人阐明。我的印象是,在ExecuteSqlCommand中设置隔离级别是没有用的,因为它只会影响那条1语句。 ExecuteSqlCommand将启动其自己的事务。尝试以下操作在您其他事务的范围内启动一个新的读未提交事务:

Contact contact;
using (var trans = context.Database.BeginTransaction(IsolationLevel.ReadUncommitted))
{
    contact = context.Contact.SingleOrDefault(x => x.ContactId == intId);
    trans.Commit(); // not sure if this matters for a read
}