ADO.NET实体框架和标识列

49

Entity Framework是否支持自增长列?

我正在使用SQL Server 2005 Express版本,有几个表的主键是自增长列。当我使用这些表创建实体模型,并将模型与实体数据源结合使用,绑定到FormView以创建新实体时,会要求我为自增长列输入值。是否有办法让框架不要要求自增长列的值?

10个回答

66

我知道这篇帖子很旧,但这可能会对下一个通过谷歌搜索"Entitiy Framework"和"Identity"到达这里的人有所帮助。

似乎Entity Framework确实尊重服务器生成的主键,就像如果设置了"Identity"属性的情况一样。然而,应用程序端模型仍需要在CreateYourEntityHere方法中提供主键。在调用上下文的SaveChanges()时,此处指定的键将被丢弃。

页面提供了详细的信息。


5

如果您正在使用Entity Framework 5,则可以使用以下属性。

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

4

您应该设置标识列的标识规范,以使(Is Identity)属性设置为true。您可以在SSMS中的表设计器中完成此操作。然后您可能需要更新实体数据模型。

也许这就是您所说的“主键是标识列”的意思,或者您可能错过了这个步骤。


3

阅读了这条建议后,我发现已经添加了一个缺失的标识符,但EF需要删除并刷新实体数据模型中的对象以修复所有问题。 - goosemanjack

2

在C#中,您可以这样做使其意识到:

在您的 FooConfiguration.cs : EntityTypeConfiguration<Foo> 文件中:

this.Property(x => x.foo).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

要使用它,只需确保将项插入上下文并在使用x.foo获取更新的自增值之前调用context.SaveChanges()。否则,x.foo将为0或null。请注意保留HTML标签。

2

Entity Framework 能够识别和处理标识列。

你的问题可能不是 EF 本身,而是它生成的表单视图。尝试从插入表单中删除标识列的输入,然后看看会发生什么。


2

如果其他方法都失败了,你可以尝试删除 EntityModel 并重新从 SQL Server 导入。如果你一直在调整键和关系,并依赖“从数据库更新模型”功能,我发现在 RC 版本中它仍然有点不稳定 - 进行全新的导入可能会有所帮助。


7年后这仍然是正确的。刷新无法捕捉到我的密钥更改。创建一个新模型解决了这个问题。 - mr_plum

1

由于某些原因,实体框架无法完全理解标识。正确的解决方法是将该列的Setter设置为私有。这将使任何生成的UI了解它不应设置标识值,因为它无法设置私有字段。


在这种情况下,您将无法通过键编辑实体,因为更新后的对象值将为0,并且您将无法通过键在集合中找到对象以保存更新的更改。 (此情况适用于MVC) - Chinjoo

0

对我来说有效的方法是将StoreGeneratedPattern设置为None(当它是一个Identity列时)。现在一切都可以正常工作了。主要问题在于,如果您有许多模型,则编辑模型是一项极其繁琐的任务。


0

我简直不敢相信。在保存更改后,Intellisensing ItemCollection返回ID = 0的单个项。

            Dim ItemCollection = From d In action.Parameter
            Select New STOCK_TYPE With {
                        .Code = d.ParamValue.<Code>.Value,
                        .GeneralUseID = d.ParamValue.<GeneralUse>.Value,
            }


            GtexCtx.STOCK_TYPE.AddObject( ItemCollection.FirstOrDefault)
            GtexCtx.SaveChanges()

无论我做了什么,在删除了我的模型、35次构建和重建、实验和编辑EDMX的XML后,现在几乎要删除整个SQL Server数据库。在第36次编译时,这个令人难以置信的解决方案终于奏效了。
            Dim abc = ItemCollection.FirstOrDefault
            GtexCtx.STOCK_TYPE.AddObject(abc)
            GtexCtx.SaveChanges()

abc.ID返回41(我需要的标识)

编辑:这里有一个简单的代码,用于循环AddObject并仍然获取ID

Dim listOfST As List(Of STOCK_TYPE) = ItemCollection.ToList()
      For Each q As STOCK_TYPE In listOfST 
         GtexCtx.STOCK_TYPE.AddObject(q)
      Next
 GtexCtx.SaveChanges()

...more code for inter-relationship tables

尝试在SaveChanges后使用Intellisence listOfST,您会发现更新的ID。也许有更好的方法,但概念是一样的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接