我正在使用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中使用它?它不必使用交易 - 无论是什么使其有效。
答案 0 :(得分:2)
如果您的数据库在UNIQUE
上有Sid
约束,则第一个语句(唯一可能导致您描述错误的语句)永远不会失败。可以?这应该。这是唯一的方式,以确保sid
真正,全球唯一。