首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >属性是键的一部分,因此不能修改或标记为修改(ForeignKey不是键)

属性是键的一部分,因此不能修改或标记为修改(ForeignKey不是键)
EN

Stack Overflow用户
提问于 2022-09-13 14:11:24
回答 1查看 1.6K关注 0票数 3

我有两个没有键关系的实体,当我想编辑人事代码字段时,这个错误会显示给我。'The property 'Personnel.PersonnelCode' is part of a key and so cannot be modified or marked as modified. To change the principal of an existing entity with an identifying foreign key, first delete the dependent and invoke 'SaveChanges', and then associate the dependent with the new principal.' EnrolNumberPersonnelNum表也没有与我的表中更改的人事记录有关联的记录

人事班

代码语言:javascript
复制
public class Personnel : BaseEntity, IBaseEntityTypeConfiguration<Personnel>
    {
        public Personnel()
        {
            EnrolNumberPersonnelNums = new HashSet<EnrolNumberPersonnelNum>();
        }
        [Key]
        public int PersonnelId { get; set; }
        public string PersonnelCode { get; set; }
        public virtual ICollection<EnrolNumberPersonnelNum> EnrolNumberPersonnelNums { get; set; }

        public void Map(EntityTypeBuilder<Personnel> builder)
        {
            builder.ToTable("Personnel", "HR");

            builder.Property(e => e.PersonnelCode).HasMaxLength(50);
        }
    }

EnrolNumberPersonnelNum类

代码语言:javascript
复制
 public class EnrolNumberPersonnelNum : BaseEntity, IBaseEntityTypeConfiguration<EnrolNumberPersonnelNum>
    {
        public EnrolNumberPersonnelNum()
        {
        }
        [Key]
        public int EnrolNumberPersonnelNumId { get; set; }
        public string PersonnelCode { get; set; }
        public virtual Personnel Personnel { get; set; }
     
        public void Map(EntityTypeBuilder<EnrolNumberPersonnelNum> builder)
        {
            builder.ToTable("EnrolNumberPersonnelNum", "HR");

            builder.Property(e => e.PersonnelCode)
                .HasMaxLength(50);

            builder.HasOne(c => c.Personnel).WithMany(c => c.EnrolNumberPersonnelNums)
                .HasForeignKey(c => c.PersonnelCode).HasPrincipalKey(c => c.PersonnelCode)
                .OnDelete(DeleteBehavior.ClientNoAction)
                .HasConstraintName($"FK_{nameof(EnrolNumberPersonnelNum)}_{nameof(Personnel)}_{nameof(PersonnelCode)}");
        }
    }

当我想编辑人事实体和EnrolNumberPersonnelNum表中的人事代码时出现错误信息。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-13 16:29:26

HasPrincipalKey(c => c.PersonnelCode)在这里

代码语言:javascript
复制
builder.HasOne(c => c.Personnel).WithMany(c => c.EnrolNumberPersonnelNums)
    .HasForeignKey(c => c.PersonnelCode).HasPrincipalKey(c => c.PersonnelCode)
    .OnDelete(DeleteBehavior.ClientNoAction)
    .HasConstraintName($"FK_{nameof(EnrolNumberPersonnelNum)}_{nameof(Personnel)}_{nameof(PersonnelCode)}");

Personnel实体的属性备用键标记为备用键

除了主键之外,备用键还充当每个实体实例的备用唯一标识符;它可以用作关系的目标。当使用关系数据库时,这将映射到替代键列上的唯一索引/约束的概念以及引用该列的一个或多个外键约束。

在EF中,所有类型的键(主键和备用键)都是只读,也就是说EF不允许更新它们(这是必需的,只能为新的实体提供)。这基本上是错误信息在开始时告诉您的。

属性'Personnel.PersonnelCode‘是键的一部分,因此不能修改或标记为修改。

尽管如此,如果您需要可编辑的属性,到目前为止还没有此类模型的解决方案。错误信息中的建议

若要用标识外键更改现有实体的主体,首先删除从属项并调用“SaveChanges”,然后将依赖项与新主体关联。

似乎不可行,因为很明显,您不能删除受抚养人(在您的情况下是EnrolNumberPersonnelNums),然后将他们与新的父(因为它们被删除)相关联。最终,您可以尝试在内存中加载它们,然后调用RemoveRange,修改父键,然后是SaveChanges,然后更新缓存子实例的PersonnelCode,然后调用AddRange,然后是SaveChanges。看起来不可靠/容易出错,但值得一试。

如果允许修改数据库,最好从PersonnelCode中删除EnrolNumberPersonnelNum,并创建和使用绑定到Personnel的PK的常规FK int PersonnelId。通过这种方式,您可以删除文档中提到的备用键(如果需要,只添加唯一约束)。

Tip 如果只想在列上强制执行唯一性,请定义唯一索引,而不是备用键(请参阅索引)。在EF中,备用键是只读的,并在唯一索引之上提供额外的语义,因为它们可以用作外键的目标。

这将允许将PersonnelCode of Personel更新为任何其他属性。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73704497

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档