Linq to SQL:为什么我收到IDENTITY_INSERT错误?

我正在使用Linq to SQL。 我有一个DataContext,我就是.SubmitChanges()。 插入标识字段时出错:

 当IDENTITY_INSERT设置为OFF时,无法在表'Rigs'中为identity列插入显式值。 

唯一的标识字段是“ID”,其值为0.它在DBML中定义为:

[Column(Storage="_ID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)] 

有几个外键,我已经validation它们的值与外表的内容一致。

为什么我会收到此错误?

编辑:这是查询:

 exec sp_executesql N'INSERT INTO [dbo].[Rigs]([id], [Name], [RAM], [Usage], [MoreInfo], [datetime], [UID]) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6) SELECT [t0].[id], [t0].[OSID], [t0].[Monitors] FROM [dbo].[Rigs] AS [t0] WHERE [t0].[id] = @p7',N'@p0 int,@p1 varchar(1),@p2 int,@p3 varchar(1),@p4 varchar(1),@p5 datetime,@p6 int,@p7 int',@p0=0,@p1='1',@p2=NULL,@p3='4',@p4='5',@p5=''2009-03-11 20:09:15:700'',@p6=1,@p7=0 

尽管从未被赋予价值,但显然它正在传递零。

编辑:添加代码:

 Rig rig = new Rig(); int RigID; try { // Confirmed these always contain a nonzero value or blank RigID = int.Parse(lbSystems.SelectedValue ?? hfRigID.Value); if (RigID > 0) rig = mo.utils.RigUtils.GetByID(RigID); } catch { } rig.Name = Server.HtmlEncode(txtName.Text); rig.OSID = int.Parse(ddlOS.SelectedValue); rig.Monitors = int.Parse(txtMonitors.Text); rig.Usage = Server.HtmlEncode(txtUsage.Text); rig.MoreInfo = Server.HtmlEncode(txtMoreInfo.Text); rig.RigsToVideoCards.Clear(); foreach (ListItem li in lbYourCards.Items) { RigsToVideoCard r2vc = new RigsToVideoCard(); r2vc.VCID = int.Parse(li.Value); rig.RigsToVideoCards.Add(r2vc); } rig.UID = c_UID > 0 ? c_UID : mo.utils.UserUtils.GetUserByToken(this.Master.LiveToken).ID; if (!mo.utils.RigUtils.Save(rig)) throw new ApplicationException("There was an error saving your Rig. I have been notified."); hfRigID.Value = rig.id.ToString(); public static User GetUserByToken(string token) { DataClassesDataContext dc = new DataClassesDataContext(ConfigurationManager.ConnectionStrings["MultimonOnlineConnectionString"].ConnectionString); return (from u in dc.Users where u.LiveToken == token select u).FirstOrDefault(); } 

另外,我注意到当我更新现有装备(insertonsubmit)时,它不会更新。 Profiler甚至不显示正在运行的任何查询。

您的代码是否明确将ID值设置为0? (而不是保持不变)。

更新1:当您在更新版本上发布时,linq2sql显然将值传递给db。 这是一个我没有遇到任何麻烦:

 [Column(Storage="_CustomerID", AutoSync=AutoSync.Always, DbType="Int NOT NULL IDENTITY", IsDbGenerated=true)] public int CustomerID 

我刚看到另一个,它与你正在使用的那个具有相同的确切定义。

 [Column(Storage="_TestID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)] public int TestID 

更新2:关于更新,您不应该为此执行InsertOnSubmit。 只需更新值并调用.SubmitChanges(应抛出exception)。 在插入它真的很奇怪,因为你发布的属性属性似乎是正确的,所以Insert方法linq2sql生成也应该是正确的。 我会尝试,再次在设计器上重新添加表格并validation所有属性是否正确。

请注意,生成的insert方法应该看起来像(使用matchingRig_Insert):

 private void InsertRig(Rig obj) { System.Nullable p1 = obj.Id; 

this.Rig_Insert(/ *一堆值* /,ref p1); obj.Id = p1.GetValueOrDefault(); }

我对发生的事情的理论如下:

  1. 您设计并创建了DataBase
  2. 您在Visual Studio中使用LINQ TO SQL创建了数据库上下文
  3. 您忘记将自动标识设置为您的表
  4. 您通过转到DataBase并设置自动标识来修复此问题
  5. 但是你忘了重新创建/更新你的LINQ TO SQL DB上下文!

:d

确保该列的dbml中的属性“自动生成的值”设置为true。 如果没有,LINQ将尝试根据类型默认值。

如果要提供IDENTITY列的值,则必须添加

 SET IDENTITY_INSERT ON 

在您的SQL语句之前,和

 SET IDENTITY_INSERT OFF 

之后将其关闭。 这适用于任何原始SQL。 如果您使用LINQ创建一个对象,如:

 var customer = new LinqContext.Customer; customer.FirstName = "Bob"; customer.LastName = "Smith"; LinqContent.Customer.Add(customer); LinqContext.SubmitChanges(); 

我相信这会奏效,如果我上课错了,请原谅我。 你得到了基本的想法。

编辑:哎呀..对不起,没有读完整个问题,我把它拿回来,累了,疲惫不堪……

看起来你的ID被分配到某个地方(即使只是默认为0) – 你是否愿意发布一些LINQ代码?

我遇到了完全相同的问题。

我的解决方案是手动将标识INT列变为可空的 INT? DBML设计器中的列,当然不在DB的实​​际表中。 同时将DbType设置为NULL而不是NOT NULL。 像这样:

 [Column(Storage="_TestID", AutoSync=AutoSync.OnInsert, DbType="Int NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)] public int? TestID 

这适用于所有数据库操作。 插入时只需将标识列设置为NULL而不是0。

我的情况,我忘了在将Id列设置为identity后更新我的dbml文件。