C# Linq到SQL:防止创建重复项
考虑下面的简单用户表 我想编写Linq to SQL代码,通过一些谓词(例如电子邮件地址)返回用户,或者如果用户还不存在,则创建该用户。代码可能看起来像C# Linq到SQL:防止创建重复项,c#,sql,linq,linq-to-sql,C#,Sql,Linq,Linq To Sql,考虑下面的简单用户表 我想编写Linq to SQL代码,通过一些谓词(例如电子邮件地址)返回用户,或者如果用户还不存在,则创建该用户。代码可能看起来像 User GetUser(String name, String email) { using (var context = new DataContext()) { User user = context.Users.FirstOrDefault(u => u.email.Equals(email));
User GetUser(String name, String email) {
using (var context = new DataContext()) {
User user = context.Users.FirstOrDefault(u => u.email.Equals(email));
if (user != null)
return user;
user = new User() { name = name, email = email };
context.Users.InsertOnSubmit(user);
context.SubmitChanges();
return user;
}
}
代码可以并行执行,但不应创建重复的用户
出于几个原因,我不希望为表创建唯一的约束。您是否看到可以使用Linq To SQL在不接触数据库的情况下实现的任何替代方案?使用
TransactionScope
(默认情况下为可序列化隔离级别):
关于LINQ to Sql中事务支持的更多信息:您的代码是否已经检查过是否存在重复项?这将导致死锁,而不是创建重复项。但至少它是安全的,并且它与L2S.usr一样好-您能描述一下在这种情况下OP的死锁示例吗?是的,冲突的情况。两个事务都读取和S锁,然后两个事务都尝试写入和X锁。经典的死锁。在这种情况下,如果没有可序列化,就会插入重复的行。我对此进行了投票。这是一个明智的解决方案。不过,它将受益于重试循环。
User GetUser(String name, String email)
{
using (var tran = new TransactionScope())
{
using (var context = new DataContext())
{
User user = context.Users.FirstOrDefault(u => u.email.Equals(email));
if (user != null)
return user;
user = new User() { name = name, email = email };
context.Users.InsertOnSubmit(user);
context.SubmitChanges();
tran.Complete();
return user;
}
}
}