6

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

当 IDENTITY_INSERT 设置为 OFF 时,无法在表“Rigs”中插入标识列的显式值。

唯一的身份字段是“ID”,其值为 0。它在 DBML 中定义为:

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

有一些外键,我已经验证它们的值与外表的内容相匹配。

为什么我会收到此错误?

编辑:这是查询:

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 甚至不显示正在运行的任何查询。

4

7 回答 7

11

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

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

:D

于 2014-04-30T15:04:42.417 回答
7

您的代码是否将 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 (应该抛出异常)。在插入时真的很奇怪,因为您发布的属性似乎是正确的,所以 linq2sql 生成的 Insert 方法也应该是正确的。我会尝试,再次在设计器上重新添加表格并验证所有属性是否正确。

请注意,生成的插入方法应如下所示(使用 matchRig_Insert):

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

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

于 2009-03-12T02:08:27.350 回答
2

确保该列的 dbml 中的属性 Auto Generated Value 设置为 true。如果不是,LINQ 将尝试根据类型默认值。

于 2010-11-17T20:28:06.833 回答
1

如果您提供 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();

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

编辑:哎呀..对不起,没有阅读整个问题,我把它收回了,因为工作累了...

于 2009-03-12T02:17:53.070 回答
1

似乎您的 ID 被分配到某个地方(即使只是默认为 0) - 您是否愿意发布一些 LINQ 代码?

于 2009-03-12T03:02:56.657 回答
0

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

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

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

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

于 2015-03-12T10:09:42.687 回答
0

我的情况是,在将 Id 列设置为标识后,我忘记更新我的 dbml 文件。

于 2016-10-05T03:32:35.843 回答