Linq to SQL:为什么我会收到 IDENTITY_INSERT 错误?
我正在使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我对发生的情况的理论如下:
:D
My theory of what happened is as follows:
:D
您的代码是否将 ID 值明确设置为 0? (而不是保持原样)。
更新 1: 正如您在更新版本上发布的那样,linq2sql 显然正在将值传递给数据库。 这是我没有遇到任何问题的一个:
我刚刚看到了另一个,它的定义与您正在使用的定义完全相同。
更新2:关于更新,您不应该为此执行InsertOnSubmit。 只需更新值并调用 .SubmitChanges (应该抛出异常)。 在插入时,这真的很奇怪,因为您发布的属性似乎是正确的,所以 linq2sql 生成的 Insert 方法也应该是正确的。 我会尝试再次在设计器上重新添加表格并验证所有属性是否正确。
请注意,生成的插入方法应类似于(带有匹配的Rig_Insert):
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:
I just saw another one, and it has the same exact definition of the one you are using.
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):
this.Rig_Insert(/* bunch of values */, ref p1);
obj.Id = p1.GetValueOrDefault();
}
确保 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.
如果您要提供 IDENTITY 列的值,则必须
在 SQL 语句之前和
之后添加以将其关闭。 这适用于任何原始 SQL。 如果您使用 LINQ 创建一个对象,例如:
我相信这会起作用,如果我的类错误,请原谅我。 你明白了基本的想法。
编辑:哎呀..抱歉,没有阅读整个问题,我收回它,工作累了......
If you are supplying the value of the IDENTITY column, you must add
before your SQL Statements, and
after to turn it off. That goes for ANY raw SQL. If you used LINQ to create an object like:
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...
似乎您的 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?
我遇到了完全相同的问题。
我的解决方案是手动将身份 INT 列变成可为空的 INT? DBML 设计器中的列,当然不是数据库的实际表中的列。 还要将 DbType 设置为 NULL 而不是 NOT NULL。 就像这样:
这适用于所有数据库操作。 插入时,只需将标识列设置为 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:
This works with all DB operations. When inserting simply set the identity column to NULL rather than to 0.
我的情况是,在将 Id 列设置为身份后,我忘记更新我的 dbml 文件。
my case, I forgot to update my dbml file after setting Id column to identity.