【问题标题】:LINQ To SQL ignore unique constraint exception and continueLINQ To SQL 忽略唯一约束异常并继续
【发布时间】:2010-04-14 10:10:09
【问题描述】:

我在名为 Users 的数据库中有一个表

用户 ------ ID(PK,身份) 用户名(唯一索引)

我在用户名表上设置了一个唯一索引以防止重复。然后我枚举一个集合并在数据库中为每个项目创建一个新用户。

我想要做的只是插入一个新用户并在违反唯一键约束时忽略异常(因为在这种情况下它显然是重复记录)。这是为了避免必须制作where not exists类型的查询。

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

我的另一个问题与 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(即使循环继续迭代),所有下一个插入都会失败 - 即使表中没有会导致唯一违规的行。

谁能解释一下?

附:我能找到的唯一解决方法是每次在插入之前实例化 repo,然后它完全按照例外情况工作 - 表明它与 LINQ To SQL DataContext 有关。

谢谢。

【问题讨论】:

  • 我在写之前的帖子时误读了你的代码,所以我的回答完全错误,这就是我删除它的原因。

标签: c# sql-server linq-to-sql caching


【解决方案1】:

在第二次插入时,dataContext 将再次尝试插入第一个对象,因为它位于此 dataContext 的标识映射中(您插入“Tim”的愿望仍然悬而未决 - 在第一次捕获之后)。

在第一个循环中,您将插入“Tim” 在第二个“蒂姆”和“鲍勃” 在第三个“蒂姆”、“鲍勃”和“约翰”中 因此,您不会在第二个循环中仅插入“Bob”,这就是失败的原因。

您可以尝试从缓存中的 DataContext 中删除失败的名称,但无论如何在一个数据上下文中多次提交是非常糟糕的主意(我对此感到很恼火)。

【讨论】:

    【解决方案2】:

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

    我认为您对 Linq-to-Sql 中的内部缓存感到困惑,这就是为什么重新创建 DataContext 可以解决问题,当您新建 DataContext 时,新对象的缓存将为空。

    【讨论】:

      【解决方案3】:

      您应该使用 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);
          }
      }
      

      【讨论】:

      • 这不是并发安全的。
      【解决方案4】:

      很难说你的方法是否“更有效”。这取决于您获得重复帐户的频率。如果您的比率非常高,那么您会失去速度,因为处理异常可能需要更多时间而不是检查记录是否存在。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-09
        • 1970-01-01
        相关资源
        最近更新 更多