ADO.NET Entity Framework 和标识列

Posted

技术标签:

【中文标题】ADO.NET Entity Framework 和标识列【英文标题】:ADO.NET Entity Framework and identity columns 【发布时间】:2010-09-12 08:30:58 【问题描述】:

实体框架是否知道标识列?

我使用的是 SQL Server 2005 Express Edition,并且有几个表,其中主键是标识列。当我使用这些表创建实体模型并将模型与实体数据源结合使用以创建新实体时,我被要求为标识列输入一个值。有没有办法让框架不要求标识列的值?

【问题讨论】:

【参考方案1】:

我知道这篇文章已经很老了,但这可能有助于下一个到达的人通过 Google 搜索“实体框架”和“身份”来听到。

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

here 页面提供了有关此的详细信息。

【讨论】:

【参考方案2】:

这是我见过的最好的答案。您必须手动编辑存储层 xml 以在每个 UniqueIdentifier 类型的主键上设置 StoreGeneratedPattern="Identity",其默认值设置为 NewID()

http://web.archive.org/web/20130728225149/http://leedumond.com/blog/using-a-guid-as-an-entitykey-in-entity-framework-4/

【讨论】:

看了这个建议后,我发现添加了一个丢失的标识,但是EF需要删除并刷新实体数据模型中的对象来修复所有问题。【参考方案3】:

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

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

【讨论】:

【参考方案4】:

在 C# 中,你可以做这样的事情来让它知道:

在你的FooConfiguration.cs : EntityTypeConfiguration<Foo>:

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

然后要使用它,只需确保将项目插入上下文并在使用x.foo 之前调用context.SaveChanges() 以获取更新的自动递增值。否则x.foo 将只是 0 或 null。

【讨论】:

【参考方案5】:

对我有用的是将 StoreGeneratedPattern 设置为 None,当它是一个 Identity 列时。现在一切正常。这样做的主要问题是,如果您有很多模型,那么编辑模型是一件非常麻烦的事情。

【讨论】:

【参考方案6】:

我不敢相信。智能感知 ItemCollection 在 SaveChanges 后生成 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()

不管我做什么。 8 小时后,包括删除我的模型、35 次构建和重建、试验和编辑 EDMX 的 XML,现在几乎要删除我的整个 SQL Server 数据库。在第 36 次编译时,这个令人瞠目结舌的解决方案奏效了

            Dim abc = ItemCollection.FirstOrDefault
            GtexCtx.STOCK_TYPE.AddObject(abc)
            GtexCtx.SaveChanges()

abc.ID yield 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。也许有更好的方法,但概念就在那里

【讨论】:

【参考方案7】:

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

【讨论】:

在这种情况下,您将无法通过键编辑实体,因为更新后的对象的值为 0,并且您无法保存更新的更改,因为您找不到对象通过密钥在集合中。 (本案例适用于MVC)【参考方案8】:

如果在你扯掉头发之前一切都失败了 - 尝试删除你的 EntityModel 并从 SQL Server 重新导入。如果您一直在调整键和关系并依赖“从数据库更新模型”功能,那么在我发现的 RC 版本中它仍然存在一些错误 - 新的导入可能会有所帮助。

【讨论】:

这在 7 年后仍然成立。刷新没有收到我的密钥更改。创建一个新模型解决了这个问题。【参考方案9】:

您应该设置标识列的标识规范,以便将 (Is Identity) 属性设置为 true。您可以在 SSMS 的表设计器中执行此操作。那么您可能需要更新实体数据模型。

也许你所说的“主键是一个标识列”是什么意思,或者你错过了这一步。

【讨论】:

【参考方案10】:

Entity Framework 知道并且可以处理标识列。

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

【讨论】:

以上是关于ADO.NET Entity Framework 和标识列的主要内容,如果未能解决你的问题,请参考以下文章

ADO.NET Entity Framework 和 NHibernate - 何时使用其中之一

ADO.NET Entity Framework 的实际好处是啥?

ADO.NET Entity Framework 如何查看T

ADO.NET Entity Framework 和标识列

ado.net entity framework无法更新数据库

带有 ADO.NET Entity Framework 的内部类