无法更新 Entity Framework Core 中的标识列
Posted
技术标签:
【中文标题】无法更新 Entity Framework Core 中的标识列【英文标题】:cannot update identity column in Entity Framework Core 【发布时间】:2016-08-26 23:42:17 【问题描述】:我已向名为 NumericId 的 AspNetUsers 表添加了一个单独的标识,它将与 ASP 默认具有的 GUID 类似的 ID 一起提供服务。
我已将该属性添加为 ApplicationUser 类的附加属性:
public class ApplicationUser : IdentityUser
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public virtual int NumericId get; set;
但是,当我尝试注册或更新用户的详细信息(甚至与 numericId 无关)时,我不断收到错误消息
SqlException: Cannot update identity column 'NumericId'.
这会阻止任何更改,最终不会更新用户(但它确实注册了一个,并且在该部分正确分配了数字 ID。但这无关紧要)
【问题讨论】:
你在使用 Fluent API 吗? OnModelCreating 方法中对 NumericId 的任何处理? 不是直接的。我只是将Add-Migration
命令用于ApplicationDBContext
,它会生成用于更新数据库的代码。Update-Database
命令。
看起来像一个错误。 EF 正在尝试将值插入到数据库生成的列中。你能submit a new issue吗?
从技术上讲,它甚至不应该插入。该值已设置,调用的方法应该只是“更新”。我可以尝试使该属性为空,也许它会忽略它,但我担心这样做会造成一些损害。
缺失:引发异常的实际代码。
【参考方案1】:
asp.net core 3.1的解决方案
modelBuilder.Entity<Type>().Property(u => u.Property).Metadata.SetAfterSaveBehavior(PropertySaveBehavior.Ignore);
【讨论】:
我可以确认这确实有效,但在修复了带有自定义问题的脚手架更新之前,此解决方案将被淘汰,并且在您需要从数据库第一种方法更新模型时必须重新输入.也许使用它的更好方法是为此创建一个单独的类,而不是将其直接放在您的 dbContext 文件中 @mighty_mite 是的。你说的对。但我将此用于代码优先方法。 这也为我解决了一个问题。但是我不明白为什么特定实体需要这个?我的代码中只有一个实体似乎需要这一行 - 如果没有它,所有其他实体都可以正常更新吗? 感谢 @HO3EiN,它在 Core 3.1 的代码优先方法中对我有用【参考方案2】:根据围绕此问题的 discussion on GitHub,对于 EF Core 2.0,我们需要使用其他帖子中建议的两行代码。
对于实体框架核心 2.0,“IsReadOnlyAfterSave”属性为 已弃用。使用以下:
builder.Property(p => p.Id)
.UseSqlServerIdentityColumn();
builder.Property(p => p.Id)
.Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore;
【讨论】:
【参考方案3】:这是 EF Core 1.0 的一个错误。见EF trying to Insert into Identity field.
EF Core 1.2 已将该问题标记为已修复,但不更新的解决方法是使用
modelBuilder.Entity<Type>().Property(u => u.Property).UseSqlServerIdentityColumn();
【讨论】:
***.com/questions/49715467/…【参考方案4】:如果您使用的是 EF Core 2.1,可以尝试一下。
builder.Property(e => e.ColumnName).Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore;
它对我有用。
IsReadOnlyAfterSave 已弃用。
【讨论】:
【参考方案5】:我找到了另一个解决方案(我使用的是 .NET Core 2.1):
using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using YetAnotherERP.Data;
using YetAnotherERP.Entities;
using YetAnotherERP.Exceptions;
using YetAnotherERP.Utils;
namespace YetAnotherERP.Services
public class EmployeeRepository : IEmployeeRepository
private DataContext _context;
public EmployeeRepository(DataContext dataContext)
_context = dataContext;
....
public async Task UpdateEmployee(Employee employee)
_context.Update(employee).Property(x=>x.Id).IsModified = false;
_context.SaveChanges();
【讨论】:
【参考方案6】:这条线解决了我的问题。 从 1.1.1 开始提供
modelBuilder.Entity<ApplicationUser>().Property(u => u.NumberId).Metadata.IsReadOnlyAfterSave = true;
【讨论】:
【参考方案7】:使用 3.1,关键是要确保您正在更新的对象的标识值与数据库中记录的值相匹配。所以如果你的对象的ID是0,而数据库中对应行的ID是99,在你尝试保存之前,请确保对象的ID值设置为99。
【讨论】:
试过这个。结果相同。我仍然收到,无法更新身份列“id”错误。【参考方案8】:其实这是由实体框架自己创建主键造成的 虽然我们在 userIdentity 中有一个 Id 列 我在 DBContext 中的 onModelCreation 函数中解决了它
base.OnModelCreating(modelBuilder);
【讨论】:
【参考方案9】:基于 GitHub here 上的线程,键(双关语)是将属性标记为备用键,因此 EF Core 在后续更新中不会尝试为基础标识列设置值这是只读的。
在引擎盖下它可能与其他答案一样,但这将是修复它的语义正确方法。
Fluent 风格的配置:
entityTypeBuilder.HasAlternateKey(e => e.NumericId);
【讨论】:
【参考方案10】:就我而言(核心 3.1), 我注意到,我被错误地标记为标识另一列, 当我将真实列作为键签名时问题解决了
【讨论】:
【参考方案11】:asp.net core 5 EF 5的解决方案
modelBuilder.Entity<Type>().Property(u => u.Property).ValueGeneratedOnUpdate().Metadata.SetAfterSaveBehavior(PropertySaveBehavior.Ignore);
【讨论】:
ValueGeneratedOnUpdate
和 SetAfterSaveBehavior(PropertySaveBehavior.Ignore)
。那就是:什么都不做。以上是关于无法更新 Entity Framework Core 中的标识列的主要内容,如果未能解决你的问题,请参考以下文章
ado.net entity framework无法更新数据库
Nuget PM 中无法识别 Entity Framework Core 命令
无法使用 Entity Framework 和 Visual Studio 2015 添加迁移
Entity Framework Core 修改期间的临时值错误