如何在插入之前更新LINQ类

时间:2014-01-29 20:48:01

标签: c# sql linq

我试图在插入期间使用LINQ / SQL访问自动生成的主键。我需要在类名称属性中使用该值:

Incident inc = new Incident
{
    StartDateTime = DateTime.Now
};

Model.db.Incidents.InsertOnSubmit(inc);
inc.Name = "Incident #" + inc.ID;

try
{
    Model.db.SubmitChanges();
}
catch (Exception e)
{
    Console.WriteLine(e);
    Model.db.SubmitChanges();
}

我可能会以错误的方式解决这个问题。任何援助将不胜感激。感谢。

3 个答案:

答案 0 :(得分:2)

您需要进行双重提交,因为自动生成的ID不会被设置,直到"插入"命令已发送到数据库。

    Incident inc = new Incident
    {
        StartDateTime = DateTime.Now
    };

    Model.db.Incidents.InsertOnSubmit(inc);
    inc.Name = "Incident #" + inc.ID;
    try
    {
        Model.db.SubmitChanges();
        inc.Name = "Incident #" + inc.ID;
        Model.db.SubmitChanges();
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
        Model.db.SubmitChanges();
    }

显然,两次到数据库的往返并不是最佳选择。我考虑设置一个存储过程,使用" scope_identity"设置"名称"立即插入列。或者,更好的是,设置一个可以完成工作的数据库触发器 - 这种方式不需要任何编码更改,并且您可以继续使用Linq插入。

答案 1 :(得分:2)

Id是在Db级别给出的,所以你必须先保存它;

Incident inc = new Incident
    {
        StartDateTime = DateTime.Now
    };

    Model.db.Incidents.InsertOnSubmit(inc);

    try
    {
        Model.db.SubmitChanges();
        inc.Name = "Incident #" + inc.ID;
        Model.db.SubmitChanges()
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
        Model.db.SubmitChanges();
    }

答案 2 :(得分:2)

这可能是一个存储过程(仍可在Linq中使用)可能非常合适的时间。

因此,我将概述两种方法来处理这个问题:一种方法可以提高工作效果,但性能更佳,第二种只是修改代码以使其按原样运行。

为什么您的代码不起作用 原因是,在进行插入之前无法获取ID - 它还不存在。

所以,在Linq,你需要

  
      
  1. 插入新记录
  2.   
  3. 更新名称以包含生成的ID
  4.   
  5. 再次保存
  6.   

这将导致2次完整的数据库往返;


为避免两次往返数据库,您可以在SQL中创建一个简单的存储过程,并将其拖到Linq类中,它将作为方法提供。

在存储过程中,您将插入新记录,然后立即使用生成的ID更新名称:

的伪代码:

Create Procedure dbo.Incident_InsertAndUpdateName
@ ... [ your entity vars ]
As 
  Begin
   Insert Into [ table ]
   Select @[your list of vars]

   Declare @NewID int
   Set @NewID = Select @@Identity

   Update [ table ]
   Set Name = "Incident #" + Convert(Varchar(10), @NewID)
   Where ID = @NewID
 End

然后,在Linq中,一旦将存储过程放入DBML类中,您只需调用

// by dragging the Stored Proc from designer onto your Incident table, 
// LINQ will generate a mapping from the stored procedure to the Incidents entity 
// such that you don't have to map the fields yourself
Model.db.Incident_InsertAndUpdateName(inc); 

这是高效的方式;修改你的代码,你可以这样做:

    Incident inc = new Incident
    {
        StartDateTime = DateTime.Now
    };

    Model.db.Incidents.InsertOnSubmit(inc);
    try
    {
        Model.db.SubmitChanges();
        inc.Name = "Incident #" + inc.ID;
        Model.db.SubmitChanges();
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
    }