【问题标题】:In Entity Framework, getting the value of an identity column after inserting在实体框架中,插入后获取标识列的值
【发布时间】:2011-09-12 11:59:57
【问题描述】:

我正在使用 EF4。我想在数据库中插入一个新的 MyObject。 MyObject 有两个字段:

Id:int(身份)和 名称:字符串

正如我在文档中看到的,实体框架应该将 MyObject.Id 设置为调用 SaveChanges() 后数据库生成的值,但在我的情况下,这不会发生。

using (var context = new MyEntities())
{
    var myObject = MyObjects.CreateMyObject(0, "something"); // The first parameter is identity "Id"
    context.MyObjects.AddObject(myObject);
    context.SaveChanges();
    return myObject.Id; // The returned value is 0
}

更新:

这发生在我的一个实体中,其他实体工作正常。顺便说一句,我检查了 DB 列是身份,StoreGeneratedPattern 设置为身份。 这是SSDL。我看不出有什么不同。第一个工作不正常:

    <EntityType Name="OrgUnit">
      <Key>
        <PropertyRef Name="Srl" />
      </Key>
      <Property Name="Srl" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
      <Property Name="TypeId" Type="smallint" Nullable="false" />
      <Property Name="Name" Type="varchar" Nullable="false" MaxLength="80" />      
    </EntityType>

    <EntityType Name="OrgType">
      <Key>
        <PropertyRef Name="Srl" />
      </Key>
      <Property Name="Srl" Type="smallint" Nullable="false" StoreGeneratedPattern="Identity" />
      <Property Name="Title" Type="varchar" Nullable="false" MaxLength="120" />
      <Property Name="Options" Type="int" Nullable="false" />
    </EntityType>

在数据库中成功完成更新并生成身份,但实体对象没有更新为新身份。

【问题讨论】:

  • 在这种情况下,您的 EF 模型可能不是最新的 - EF 应该自动从数据库中获取您的新 ID。尝试刷新您的 EF 模型

标签: entity-framework identity-column


【解决方案1】:

如果您像我一样使用来自 ODP.NET 的 Oracle Entity Framework 4 Provider,则 Designer 中存在错误。仅在下拉框中选择 Identity 值是行不通的。它将用

注释概念模型中的概念属性

注解:StoreGeneratedPattern="Identity"

喜欢

<Property Type="Int32" Name="Id" Nullable="false" cg:SetterAccess="Private" annotation:StoreGeneratedPattern="Identity" />

但是,它不会对存储模型做同样的事情,即。你需要手动完成。在感兴趣的 EntityType 中找到属性(在我的情况下为 ID)并添加 StoreGeneratedPattern="Identity"。

    <EntityType Name="PROBLEMI">
      <Key>
        <PropertyRef Name="ID" />
      </Key>
      <Property Name="ID" Type="number" Nullable="false" Precision="10" StoreGeneratedPattern="Identity" />

我不知道 SQL EF 提供程序中存在相同的错误,因为我没有使用它。

【讨论】:

  • 这是正确答案。我一直在寻找互联网,找不到这样的解释。谢谢你。顺便说一句,这种情况应该是 Visual Studio 2010 错误的结果,有人说 Visual Studio 2010 的 Service Pack 1 解决了这个问题。我现在要试试这个更新......
【解决方案2】:

我今天遇到了这个。不同之处在于我使用的是插入函数,上面的人没有指定。我必须做的是让我的插入函数存储过程返回 SCOPE_IDENTITY() 并为返回的 id 使用结果绑定。

解决了我的问题。

【讨论】:

    【解决方案3】:

    如果您使用 Linq To Entities,并且即使您遵循了 marc_s 的建议(非常好),也会出现此错误,您应该直接在 edmx(xml 视图)中查看您的实体并检查它们是否具有以下属性:

        <EntityType Name="MyEntity">
          <Key>
            <PropertyRef Name="pk" />
          </Key>
          <Property Name="pk" Type="bigint" Nullable="false" StoreGeneratedPattern="Identity" />
          <Property Name="value" Type="float" Nullable="false" />
        </EntityType>
    

    StoreGeneratedPattern="Identity" 也是必需的。

    【讨论】:

      【解决方案4】:

      哇!那是一场噩梦,但最后我解决了,虽然我不明白问题是什么。也许这可以帮助遇到同样问题的人。

      1. 生成用于创建表及其数据的脚本。
      2. 放下桌子。
      3. 运行脚本。

      【讨论】:

        【解决方案5】:

        在这种情况下,您的 EF 模型可能不是最新的 - EF 应该自动从数据库中获取您的新 ID。尝试刷新您的 EF 模型。

        您的身份列的属性在您的 EDMX 模型中应如下所示:

        【讨论】:

          【解决方案6】:

          Save Changes 后尝试使用 refresh 方法,在 MSDN 中有记录

          "为确保客户端上的对象已被数据源端逻辑更新,您可以在调用 SaveChanges 后调用带有 StoreWins 值的 Refresh 方法。"

          http://msdn.microsoft.com/en-us/library/bb336792.aspx

          虽然我觉得@Craig 的建议也可能有效。

          【讨论】:

          • 这对于设置了StoreGeneratedPattern 的属性不是必需的。您需要这样做,例如,对于可能为触发器更新的属性。
          【解决方案7】:

          这应该“正常工作”。确保 DB 列实际上是 IDENTITY,并且 StoreGeneratedPattern 在 EDMX 中设置为 Identity。

          【讨论】:

          • 好的。这两者有什么不同。区分 EDMX 中的 SSDL。区分 DDL。有些东西不一样。
          • 我将我的 SSDL 添加到问题中,这两个实体似乎都一样。
          • 不一样。 Type 不同。我想知道这是否重要?
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-11
          • 2020-11-22
          • 2017-03-05
          • 2023-03-10
          • 2017-01-06
          • 2012-09-25
          相关资源
          最近更新 更多