I'm using Entity Framework 4.1 and have a seemingly simple requirement: I want to either get an entity by a unique key, or if it doesn't already exist, create it:
var user = db.Users.SingleOrDefault(u => u.Sid == sid);
if (user != null)
return user;
user = new User(sid);
db.Users.Add(user);
Normally this works fine, but when I run a bunch of tests together (using MSTest) one of them consistently fails with "Sequence contains more than one element". When I run that test by itself it works fine.
The problem seems obvious: multiple threads are calling the above code concurrently and each create a new User row. But what is the solution?
The proper solution is a transaction, of course, but I just cannot get it to work. EF won't use a normal DbTransaction if I start one. If I use a TransactionScope it either has no effect (the same error occurs) or EF tries and fails to start a distributed transaction, even if I follow the advice about opening a connection first.
This is really frustrating, because it is such a trivial thing to do with plain old SQL: begin transaction, SELECT, INSERT, commit transaction. How can I get this to work in EF? It doesn't have to be using transactions - whatever makes it work.
The first statement (the only one which could cause the error you describe) will never fail if your DB has a UNIQUE
constraint on Sid
. Does it? It should. That's the only way to make sure that the sid
is truly, globally unique.