在Entity Framework中以事务方式获取或创建数据库对象

时间:2011-08-09 14:09:04

标签: entity-framework transactions entity-framework-4.1 transactionscope

我正在使用Entity Framework 4.1并且有一个看似简单的要求:我想要通过唯一键获取实体,或者如果它尚不存在,则创建它:

        var user = db.Users.SingleOrDefault(u => u.Sid == sid);
        if (user != null)
            return user;

        user = new User(sid);
        db.Users.Add(user);

通常情况下这很好用,但是当我一起运行一堆测试时(使用MSTest),其中一个一直失败,“Sequence包含多个元素”。当我自己运行该测试时,它工作正常。

问题显而易见:多个线程同时调用上面的代码,每个线程都创建一个新的User行。但是解决方案是什么?

当然,正确的解决方案是一项交易,但我无法让它发挥作用。如果我启动EF,EF将不会使用正常的DbTransaction。如果我使用TransactionScope,它或者没有效果(发生相同的错误)或EF尝试并且无法启动分布式事务,即使我遵循the advice about opening a connection first

这真的很令人沮丧,因为对于普通的旧SQL来说这是一件微不足道的事情:begin transaction,SELECT,INSERT,commit transaction。如何在EF中使用它?它不必使用交易 - 无论是什么使其有效。

1 个答案:

答案 0 :(得分:2)

如果您的数据库在UNIQUE上有Sid约束,则第一个语句(唯一可能导致您描述错误的语句)永远不会失败。可以?这应该。这是唯一的方式,以确保sid真正,全球唯一。