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

发布于 2024-07-15 02:40:25 字数 2296 浏览 8 评论 0原文

我正在使用 Linq to SQL。 我有一个 DataContext,我正在对其进行 .SubmitChanges()'ing。 插入身份字段时出错:

Cannot insert explicit value for identity column in table 'Rigs' when IDENTITY_INSERT is set to OFF.

唯一的标识字段是“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 甚至不显示任何正在运行的查询。

I'm using Linq to SQL. I have a DataContext against which I am .SubmitChanges()'ing. There is an error inserting the identity field:

Cannot insert explicit value for identity column in table 'Rigs' when IDENTITY_INSERT is set to OFF.

The only identity field is "ID", which has a value of 0. It's defined in the DBML as:

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

There are a few foreign keys, and I've verified they have values that jive with the foreign tables' content.

Why would I be getting this error?

Edit: Here is the query:

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

Clearly it is passing a zero, despite having never been assigned a value.

Edit: Adding Code:

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();
}

Also, I notice that when I UPDATE an existing rig (insertonsubmit), it doesn't update. Profiler doesn't even show any queries being run.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

小帐篷 2024-07-22 02:40:25

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

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

:D

My theory of what happened is as follows:

  1. You designed and created the DataBase
  2. You created the DB Context using LINQ TO SQL in visual Studio
  3. You forgot to set the auto-identity to your table
  4. You fixed that by going to your DataBase and setting the auto-identity
  5. But you forgot to recreate/update your LINQ TO SQL DB Context!!!

:D

似最初 2024-07-22 02:40:25

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

更新 1: 正如您在更新版本上发布的那样,linq2sql 显然正在将值传递给数据库。 这是我没有遇到任何问题的一个:

[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 方法也应该是正确的。 我会尝试再次在设计器上重新添加表格并验证所有属性是否正确。

请注意,生成的插入方法应类似于(带有匹配的Rig_Insert):

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

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

Is your code setting the ID value explicitely to 0? (instead of leaving it untouched).

Update 1: As you posted on the updated version, linq2sql is clearly passing the value to the db. Here is one I haven't had any trouble with:

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

I just saw another one, and it has the same exact definition of the one you are using.

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

Update 2: Regarding updates, you are not supposed to do InsertOnSubmit for that. Just update the values and call .SubmitChanges (should be throwing an exception). On the insert it is really weird, as the property attributes you posted seems to be correct, so the Insert method linq2sql generates should be correct as well. I would try, re-adding the table on the designer again and verifying all the properties are correct.

Note that the generated insert method should look like (with a matchingRig_Insert):

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

this.Rig_Insert(/* bunch of values */, ref p1);
obj.Id = p1.GetValueOrDefault();
}

拥抱我好吗 2024-07-22 02:40:25

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

Ensure the property Auto Generated Value in your dbml for that column is set to true. If not, LINQ will attempt to default the value based on the type.

你与清晨阳光 2024-07-22 02:40:25

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

我相信这会起作用,如果我的类错误,请原谅我。 你明白了基本的想法。

编辑:哎呀..抱歉,没有阅读整个问题,我收回它,工作累了......

If you are supplying the value of the IDENTITY column, you must add

SET IDENTITY_INSERT ON

before your SQL Statements, and

SET IDENTITY_INSERT OFF 

after to turn it off. That goes for ANY raw SQL. If you used LINQ to create an object like:

var customer = new LinqContext.Customer;
customer.FirstName = "Bob";
customer.LastName = "Smith";

LinqContent.Customer.Add(customer);
LinqContext.SubmitChanges();

I believe that will work, forgive me if I have classes wrong. You get the basic idea.

Edit: Oops.. Sorry, didn't read the entire question, I take it back, tired and fatigued from work...

面如桃花 2024-07-22 02:40:25

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

seems like your ID is being assigned somewhere (even if just defaulting to 0) - would you care for posting some of your LINQ code?

甲如呢乙后呢 2024-07-22 02:40:25

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

我的解决方案是手动将身份 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。

I was having the exact same problem.

My solution was to manually make the identity INT column into a nullable INT? column in the DBML designer, not in the actual table of the DB of course. Also set the DbType to NULL instead of NOT NULL. Like so:

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

This works with all DB operations. When inserting simply set the identity column to NULL rather than to 0.

花开雨落又逢春i 2024-07-22 02:40:25

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

my case, I forgot to update my dbml file after setting Id column to identity.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文