【问题标题】:EF Core - "The property is part of a key and so cannot be modified or marked as modified" errorEF Core - \“该属性是键的一部分,因此无法修改或标记为已修改\”错误
【发布时间】:2023-01-08 02:58:02
【问题描述】:

我开发了一个应用程序,其中包含语言和方言等实体。一种语言有多种方言,所以它是经典的一对多关系:

public class Language
    {
        [Required]
        [Key]
        public long LanguageId { get; set; }
        public string LanguageName { get; set; } = String.Empty;

        public IEnumerable<Dialect>? Dialects { get; set; }
    }
public class Dialect
    {
        [Required]
        [Key]
        public long DialectId { get; set; }
        public string DialectName { get; set; } = String.Empty;
        [Required]
        public long LanguageId { get; set; }

        public Language? Language { get; set; }
    }
modelBuilder.Entity<Language>()
                .HasMany(l => l.Dialects)
                .WithOne(d => d.Language)
                .HasForeignKey(d => d.DialectId);

我有一种方法可以将新方言添加到现有语言中:

public async Task<bool> AddDialectAsync(Dialect dialect)
        {
            try
            {
                var maxId = await db.Dialects.MaxAsync(x => x.DialectId);
                dialect.DialectId = maxId + 1;
                await db.Dialects.AddAsync(dialect);
                return await db.SaveChangesAsync() >= 1;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

问题是,当控制器调用 AddDialect 方法时,到达行 return await db.SaveChangesAsync() &gt;= 1; 时总是会出现异常。此时方言对象如下所示:

dialect.DialectId = 5,
dialect.DialectName = "american",
dialect.LanguageId = 1

但总有例外: “属性‘Dialect.DialectId’是键的一部分,因此无法修改或标记为已修改。要更改具有标识外键的现有实体的主体,首先删除依赖项并调用‘SaveChanges’,然后关联新校长的受抚养人。”

如果我删除 var maxId = await db.Dialects.MaxAsync(x =&gt; x.DialectId); dialect.DialectId = maxId + 1; 行,则没有任何变化。

应用程序使用 PostgreSQL 数据库。怀疑是数据库有问题,因为sql查询

INSERT INTO public."Dialects"(
    "DialectId", "DialectName", "LanguageId")
    VALUES (5, 'american', 1);

工作正常,行实际上被添加到数据库中。

应用程序使用 Entity Framework Core 7.0.1。

我没有想法,因为我相信在我以前的应用程序中有非常相似的关系,我以同样的方式做到了,然后它起作用了。

【问题讨论】:

    标签: c# asp.net-core .net-core entity-framework-core asp.net-core-webapi


    【解决方案1】:

    在这种情况下,您不应修改密钥。取而代之的是,只需设置自动增量并让 EF 为您设置它。

    【讨论】:

      【解决方案2】:

      如果您想自己设置主键,可以将 [DatabaseGenerated(DatabaseGeneratedOption.None)] 添加到 DialectId :

      public class Dialect
      {
          [Required]
          [Key]
          [DatabaseGenerated(DatabaseGeneratedOption.None)]
          public long DialectId { get; set; }
          public string DialectName { get; set; } = String.Empty;
          [Required]
          public long LanguageId { get; set; }
      
          public Language? Language { get; set; }
      }
      

      或者只是不设置任何值,无论是在 AddDialectAsync 中还是在它之外。

      【讨论】:

        猜你喜欢
        • 2021-09-08
        • 1970-01-01
        • 2020-10-15
        • 2021-07-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多