【问题标题】:Entity Framework Core attempting to update column marked as Identity in modelEntity Framework Core 尝试更新模型中标记为 Identity 的列
【发布时间】:2018-07-23 10:07:13
【问题描述】:

我有一个数据库表,其中一列是IDENTITY 列(不是手动设置的主键)。我的 EF Core 模型如下所示:

public class Model
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }

    ...Other fields...

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int AnotherId { get; set; }
}

尽管有注释,但当我对表进行更新时,我发现生成的 SQL 会尝试更新 IDENTITY 列:

UPDATE [Model] SET ... [AnotherId] = @p10 ...
WHERE [Id] = @p29;
SELECT @@ROWCOUNT;

这显然失败了,导致抛出异常。我正在使用 Entity Core 2.0,目前不能升级到 2.1。任何想法为什么忽略数据注释?

【问题讨论】:

    标签: c# sql-server entity-framework ef-core-2.0 identity-column


    【解决方案1】:

    我在 EF Core 3.1 中的解决方案是这样的:

        partial void OnModelCreatingPartial(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<YourTableName>().Property(c => c.YourPropertyName).UseIdentityColumn().ValueGeneratedOnAddOrUpdate();
        }
    

    如果没有 ValueGeneratedOnAddOrUpdate(),我在更新现有记录时看到了与 OP 相同的错误。因此它看起来好像 UseIdentityColumn() 等同于调用 ValueGeneratedOnAdd()。

    【讨论】:

      【解决方案2】:

      Context 类的OnModelCreating 中尝试Fluent API。像这样的:

      protected override void OnModelCreating(ModelBuilder modelBuilder)
      {
          modelBuilder
          .Entity<Model>()
          .Property(c => c.AnotherId )
          .UseSqlServerIdentityColumn();
      }
      

      在 EF Core 2 中也应该是这样的:

      modelBuilder.Property(c => c.AnotherId).UseSqlServerIdentityColumn();
      modelBuilder.Property(p => p.AnotherId )
                  .Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore;
      

      【讨论】:

      • 谢谢,这看起来是一个很好的答案,但我一直在尽可能使用流利的 API 上的属性,所以我将采用 @mjwills 在 cmets 中建议的解决方案。
      • @SBFrancies Fluent API 是另一种配置域类的方法。 Fluent API 提供了比 DataAnnotations 更多的配置功能。 tutorialspoint.com/entity_framework/…
      • 谢谢,我知道这一点,并且正在使用 Fluent API 来填补无法使用数据注释的空白。我只是更喜欢在可能的情况下使用数据注释,并且发现它们在很大程度上满足了我的需求。
      • 请注意,这些扩展方法应该在 Microsoft.EntityFrameworkCore.SqlServer 程序集中。
      【解决方案3】:

      您可能想要使用的属性是:

      [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
      

      根据the docs

      【讨论】:

      • 谢谢你,我在文档中仍然不清楚它是否表明[DatabaseGenerated(DatabaseGeneratedOption.Identity)] 应该发生经验行为,但这暂时解决了我的问题。
      猜你喜欢
      • 1970-01-01
      • 2020-12-06
      • 2018-03-21
      • 2018-04-07
      • 2022-01-27
      • 1970-01-01
      • 2017-09-17
      • 1970-01-01
      相关资源
      最近更新 更多