2010-03-18 78 views
6

我有一个表在数据库中调用用户LINQ到SQL忽略唯一约束异常,并继续

 
Users 
------ 
ID (PK, Identity) 
Username (Unique Index) 

我已经安装上的用户名表的唯一索引,以防止重复。然后,我通过集合进行枚举,并在每个项目的数据库中创建一个新用户。

我想要做的只是插入一个新用户,并且如果违反了唯一键约束(因为在这种情况下显然是重复记录),则忽略该异常。这是为了避免必须制造不存在种类的查询。

首先,这是否会更有效率,或者我的插入代码应该检查重复吗?我更关注具有该逻辑的数据库,因为这可以防止任何其他类型的客户端插入重复数据。

我的其他问题与LINQ To SQL有关。我有以下代码:

public class TestRepo 
{ 
    DatabaseDataContext database = new DatabaseDataContext(); 

    public void Add(string username) 
    { 
     database.Users.InsertOnSubmit(new User() { Username = username }); 
    } 

    public void Save() 
    { 
     database.SubmitChanges(); 
    } 
} 

然后我遍历集合,并插入新的用户,忽略任何例外:

TestRepo repo = new TestRepo(); 

foreach (var name in new string[] { "Tim", "Bob", "John" }) 
{ 
    try 
    { 
     repo.Add(name); 
     repo.Save(); 
    } 
    catch { } 
} 

第一次遇到这种运行,太好了,我有三个用户表。如果我删除第二个并再次运行此代码,则不会插入任何内容。我期望第一次插入失败,例外,第二次插入成功(因为我刚刚从数据库中删除了该项目),第三次失败。

看上去正在发生的是,一旦抛出SqlException(即使循环继续迭代),即使表中没有会导致唯一违规的行,所有下一次插入也会失败。

任何人都可以解释这一点吗?

P.S.我能找到的唯一解决方法是在insert之前每次都实例化repo,然后它的工作方式与例外完全一样 - 表明这与LINQ To SQL DataContext有关。

谢谢。

+0

我误解你的代码写我以前的帖子的时候,所以我的答案是完全错误的,这就是为什么我删除了它。 – 2010-03-18 15:12:20

回答

0

在测试运行之间,在您的DataContext上尝试调用DataContext.Refresh

我想你已经挂断了Linq-to-Sql中的内部缓存,这就是为什么重新创建DataContext充当解决方法,当你新建一个DataContext时,新对象的缓存将是空的。

0

你应该检查存在使用try catch技巧是不好的。

foreach (var name in new string[] { "Tim", "Bob", "John" }) 
{ 
    var u = from users in db.Users 
      where users.username == name 
      select users; 

    if (u.Count() == 0) 
    { 
     User user = new User(); 
     user.name = name; 
     db.Users.InsertOnSubmit(user); 
     db.SubmitChanges(System.Data.Linq.ConflictMode.ContinueOnConflict); 
    } 
} 
+1

这不是并发安全的。 – Simon 2013-05-09 15:36:50

1

在二次插入的DataContext将再次尝试,因为它是坐在身份相关地图的DataContext插入第一个对象(您想插入“添”仍悬而未决 - 第一抓到底)。

在第一循环中,您被排在第二循环中插入“添” 在第二个“添”和“鲍勃” 在三“添”,“鲍勃”和“约翰”只有 所以你不插入“鲍勃”这就是为什么失败。

你可以尝试从DataContext的在CACH但在一个数据上下文反正多次提交删除失败的名字是非常糟糕的主意(我被烧毁这个)。

0

这是很难说,如果你的方法是“更加有效。”这取决于您获得重复帐户的频率。如果你有一个非常高的速度,那么你就失去了速度它可能会花费更多的时间来处理异常,而不是检查记录的存在。

如果你想最大化你的速度,然后创建一个存储过程检查和插入,如果它不是在数据库中。