【问题标题】:Entity Framework Core 2 (Code First) updating value not workingEntity Framework Core 2(代码优先)更新值不起作用
【发布时间】:2018-02-24 22:11:12
【问题描述】:

一周来,我一直在努力更改数据库中的值,但无法找出我做错了什么。我设法创建表,添加和删除实体,但我无法更改实体内的值。

我得到的错误是:实体类型“Generation”上的属性“Rating”是键的一部分,因此不能修改或标记为已修改。要使用标识外键更改现有实体的主体,首先删除依赖项并调用“SaveChanges”,然后将依赖项与新主体关联。

(我不习惯principal这个词,但我认为它是具有唯一密钥的实体。我也不习惯dependent这个词数据库上下文,但我认为它是另一个表中的实体,它具有到 principal 的链接)

仅供参考:我正在使用 Microsoft.AspNetCore.All 2.0.0、Microsoft.EntityFrameworkCore 2.0.0 和 Npgsql.EntityFrameworkCore.PostgreSQL 2.0.0

我确信这条错误消息试图告诉我解决方案,但据我所知,没有什么依赖于 Rating,它不是关键。对于上下文,这里是我用于数据库中表的两个类:

[Table("Generation")]
public class Generation
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int GenerationId { get; set; }

    [Required]
    [MaxLength(100)]
    public string DNA { get; set; }
    //[Editable(true)]
    public double Rating { get; set; }

    public Generation(int ID, string dna, double rate)
    {
        GenerationId = ID;
        DNA = dna;
        Rating = rate;
    }

    public Generation()
    {

    }
}

[Table("Device")]
public class Device
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int DeviceID { get; set; }

    //[Required]
    [MaxLength(100)]
    public string Identifier { get; set; }

    //[ForeignKey("GenerationId2")] <-- should be changed to GenerationId in the near future
    public int GenerationId2 { get; set; }
    public float WaitingSeconds { get; set; }
}

(这是一个我想保存在服务器上用于遗传算法的数据库)

我用来更改数据的代码非常简单,但会导致 SaveChanges() 出错:

Generation gen = Program.Context.Generation.FirstOrDefault(g => g.Rating < 0.0);
if (gen != null)
{
gen.Rating = 10.0;
Debug.Log("DNA: About to save changes");
Program.Context.SaveChanges();
}

(创建的世代带有负面评级,表明该 DNA 尚未经过测试)

我尝试了不同的数据注释,例如 [Editable(true)]、[Required] 和 [ForeignKey]

有人可以帮我“简单地”更改表格中的一些数据吗?

亲切的问候!

坎贝萨

【问题讨论】:

  • but causes the error on SaveChanges() 有什么错误?请将其添加到您的帖子中。
  • 检查你的数据库表,“评级”是主键吗?
  • 错误在帖子第2段
  • mxmissile,感谢您的提示,我刚刚发现一切都是主键。 (标记为 [PK])如果 [Key] 数据注释无效,我将如何仅将 GenerationId 标记为主键? MaxLength 确实有效,因为它显示最大长度为 100
  • @Cambesa 您的代码中是否有一些流畅的 API 配置使用HasKey (...) 方法?

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


【解决方案1】:

在我的 OnModelCreating 方法中,我使用 HasKey 将所有内容更改为主键。

通过替换:

protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Generation>().HasKey(g => new { { g.DNA, g.GenerationId, g.Rating } });
    }

与:

protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Generation>().HasKey(g => new { g.GenerationId });
        }

它仅将世代 id 标记为主键,其他变量现在可编辑。

感谢伊万·斯托耶夫

【讨论】:

  • 这个答案也可以在这里找到:Need a help to update the model 另外,请确保您对模型进行了合理的更新。您不想意外更新,比如说,从HasKey 中删除用户的ID,然后突然之间,数据库中该用户的所有信息现在都与另一个@ 相关987654326@ 不再存在。作为提示,请确保在您的特定情况下执行此操作是可以的。
【解决方案2】:

我因不同的用例而收到此错误。 HasKey 对我来说不是问题。

我正在编写一些代码来从一个数据库获取对象图并将其迁移到另一个数据库(相同的模式)。我正在清除对象中的 GUID Id 值,因此它将被插入到目标数据库中。这并没有让实体框架高兴,我出错了:

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

为了解决这个问题,我首先清除了对象图中的所有 Id。然后Attach 对象到 DbContext。然后我可以修改状态并调用SaveChanges

诀窍是在 Entity Framework 跟踪某些内容时不要修改 Id。

【讨论】:

  • 我写的代码只是一个概念证明——我可能会把它扔掉,但我希望这个答案会对某人有所帮助。
猜你喜欢
  • 1970-01-01
  • 2020-04-29
  • 1970-01-01
  • 1970-01-01
  • 2017-05-05
  • 1970-01-01
  • 2022-11-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多