【问题标题】:Multiple LINQ to SQL insert using IDENTITY from previous insert使用先前插入的 IDENTITY 进行多个 LINQ to SQL 插入
【发布时间】:2013-02-13 16:23:25
【问题描述】:

我想尝试插入到我的 SQL Server 数据库中的多个表中,但是我的第一个插入中的一个生成了一个外键,即我想在后续插入中使用它的 IDENTITY 值。我不确定如何在 LINQ to SQL 中进行此操作。我认为我可以在多个事务中执行此操作,但我更喜欢在一个地方执行此操作……也就是在 using 子句中。

我的伪代码算法如下:

  1. 检查 TABLE1.COL2 列中是否存在 ID 值
  2. 如果不存在,则在 TABLE1 中插入一个新行
  3. 从 TABLE1.COL1 列中获取新插入行的外键值。
  4. 使用新的外键值创建一个对象并更新 TABLE2。

     using (var sms = new SmsDataDataContext(connection_string)
     {
        foreach(SomeObject i in ListofObject)
        {
          TABLE1 t1 = CheckID(sms, i.ID);
    
          if (t1== null)
          {
             TABLE1 new_row = new TABLE1();
             sms.TABLE1.InsertOnSubmit(new_row);
    
             //Ideally I want to do something like this even though i dont think it will work.
             sms.SubmitChanges();
    
    
             TABLE2 update_row = new TABLE2();
             update_row.ID = new_row.COL1.value;  //has the newly created identity value from my last insert.
             //Assume this update_row exist in my TABLE2 table.
             sms.TABLE2.InsertOnSubmit(update_row);
    
          }
        }
        sms.SubmitChanges();
      }
    

【问题讨论】:

    标签: c# sql-server linq


    【解决方案1】:

    LINQ to SQL 是围绕对象图上的工作单元模式构建的,而不是针对每一行的单独语句。假设您的父级 (Table1) 和子级 (Table2) 之间存在关联,您应该能够构建图表并发出单个 SubmitChanges。 LINQ to SQL 将根据之前提交的值自动处理设置孩子的父 ID。

    using (var sms = new SmsDataDataContext(connection_string)
     {
        foreach(SomeObject i in ListofObject)
        {
          TABLE1 t1 = CheckID(sms, i.ID);
    
          if (t1== null)
          {
             TABLE1 new_row = new TABLE1();
             sms.TABLE1.InsertOnSubmit(new_row);
    
             TABLE2 update_row = new TABLE2();
             new_row.Table2s.Add(update_row);
    
          }
        }
        sms.SubmitChanges();
      }
    

    【讨论】:

      【解决方案2】:

      您可以使用TransactionScope

      只需像这样将整个数据库调整块包装在其中:

      using (var MyTran = new TransactionScope())
      {
         try{
           //Insert #1
           //Insert #2
           ...
           MyTran.Complete();
         }catch{
           // if the flow of control comes here, transaction will not be committed
         }
      }
      

      如您所见,如果您的代码在 Complete() 执行之前执行,您将获得回滚。

      参考文献

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多