无法为标识列插入显式值

时间:2013-02-14 21:01:16

标签: vb.net entity-framework ef-code-first

创建新记录时出现上述错误。我不想插入标识 - 数据库自动生成它,这很棒。

这是一个确切的例外:

[System.Data.UpdateException]
{"An error occurred while updating the entries. See the inner exception for details."}
{"Cannot insert explicit value for identity column in table 'PartRevisions' when IDENTITY_INSERT is set to OFF."}

以下是映射:

Public Class PartContext
    Inherits DbContext

    Public Property Parts As DbSet(Of Part)
    Public Property PartRevisions As DbSet(Of PartRevision)


    Protected Overrides Sub OnModelCreating(modelBuilder As DbModelBuilder)
        MyBase.OnModelCreating(modelBuilder)

        modelBuilder.Entity(Of PartRevision)().HasKey(Function(r) r.Id).Property(Function(r) r.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
    End Sub

End Class

<Table("Parts")>
Public Class Part
    <Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)>
    Public Property Id As Integer

    Public Property PartNumber As String
    Public Property Owner As String
End Class

<Table("PartRevisions")>
Public Class PartRevision
    Inherits Part

    Public Property OriginalId As Integer
    Public Property RevisionDate As DateTime
    Public Property RevisionNumber As Integer
    Public Property RevisionBy As String

End Class

如果我不使用继承,它可以正常工作。如果我使Id可以覆盖并且还在子类上指定属性,它仍然不起作用。

我正在做OnModelCreating的事情,因为我正试图让它发挥作用。我觉得没有这个应该可以工作。当然它甚至不适用于此...

以下查询在SQL Management Studio中执行时工作正常:

insert into PartRevisions (originalid, revisiondate, revisionnumber, revisionby, partnumber, owner)
values (1, '1/1/2013', 1, 'eep', '123', 'ME')

这是完整程序的要点。我在一个测试项目中尝试这个,因为我认为我在EF中遇到了一些继承的问题(从未完成)。

https://gist.github.com/eyston/4956444

谢谢!

2 个答案:

答案 0 :(得分:2)

PartRevisions表不能将Id列设置为自动生成的标识,只能将基础类型的表Parts设置为PartRevision。这两个表具有共享主键。 EF在查询PartRevision时加入两个表,如果插入了Id实体,则会在两个表中插入行。因为两行必须具有相同的{{1}},所以只有一行可以是标识。

答案 1 :(得分:0)

从“Id”列中删除自动标识属性。或者,您也可以在查询/存储过程中使用。这样即使设置了列上的自动标识,也可以在表中输入显式Id值。 (虽然总是使用它不是一个好主意,但它对修复有好处)

SET IDENTITY_INSERT dbo.YourTableName ON;
GO

然后在每个表的插入之后:

SET IDENTITY_INSERT dbo.YourTableName OFF;
GO