自增非键值实体框架核心2.0 [英] Auto increment non key value entity framework core 2.0

查看:28
本文介绍了自增非键值实体框架核心2.0的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个对象,该对象的密钥存储为 GUID 和友好 ID,如下所示:

I've got an object that has a key stored as a GUID as well as a friendlyID, like this:

public class Job {

    [Key]
    public Guid Id { get; set; }

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

    public string Description { get; set; }
}

但是,当我尝试使用我的更新方法更新描述时:

However when I try to update description using my update method:

    public void Update(Job job, Job jobParam) {
        if (job == null) {
            throw new AppException("Job does not exist");
        }

        //Update job properties
        job.Description = jobParam.Description;


        _context.Job.Update(job);
        _context.SaveChanges();
    }

我收到一条错误消息:

System.Data.SqlClient.SqlException:无法更新标识列'FriendlyId'

System.Data.SqlClient.SqlException: Cannot update identity column 'FriendlyId'

我已确保尝试更新正确的对象,但我不明白为什么friendlyID 会在未更改的情况下尝试更新.在网上查看时,我可以看到 EF 核心 1.1 中存在一个会导致此问题发生的错误,但与 2.0 或非键值无关.

I've made sure that the correct object is trying to be updated, but I can't understand why friendlyID would try to get updated when it has not been changed. When looking online I can see that there was a bug in EF core 1.1 that would cause this issue to occur, but nothing about 2.0 or about a value that isn't a key.

推荐答案

EF Core 中生成的属性的确切行为仍处于调整过程中.EF Core 2.0 引入了两个新的属性元数据属性 - BeforeSaveBehaviorAfterSaveBehavior.没有数据注释/流畅的 API 来设置它们,默认情况下,它们是从值生成策略以及属性是否是键的一部分中隐含的.同时,它们会影响跟踪操作的行为.

The exact behavior of the generated properties in EF Core is still in a process of tweaking. EF Core 2.0 introduced two new property metadata properties - BeforeSaveBehavior and AfterSaveBehavior. There is no data annotation/fluent API for setting them and by default they are implied from value generating strategy and whether the property is part of the key. At the same time they affect the behavior of the tracking operations.

这里的问题是,对于不是键的一部分的标识列(即ValueGeneratedOnAdd),AfterSaveBehavior保存,进而使Update方法将它们标记为已修改,进而生成错误的UPDATE命令.

The problem here is that for identity columns (i.e. ValueGeneratedOnAdd) which are not part of a key, the AfterSaveBehavior is Save, which in turn makes Update method to mark them as modified, which in turn generates wrong UPDATE command.

要解决这个问题,您必须像这样设置 AfterSaveBehavior(在 OnModelCreating 覆盖中):

To fix that, you have to set the AfterSaveBehavior like this (inside OnModelCreating override):

modelBuilder.Entity<Job>()
    .Property(e => e.FriendlyId)
    .ValueGeneratedOnAdd()
    .Metadata.AfterSaveBehavior = PropertySaveBehavior.Throw; // <--

更新:在 EF Core 3.0+ 中,许多元数据属性已被替换为 Get/Set 方法,因此只需使用相应的方法:

Update: In EF Core 3.0+ many metadata properties have been replaced with Get/Set methods, so just use the corresponding method:

.Metadata.SetAfterSaveBehavior(PropertySaveBehavior.Throw);

这篇关于自增非键值实体框架核心2.0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆