更新EF Core中的相关实体

时间:2020-05-18 13:35:15

标签: entity-framework-core

我正在使用带有代码优先方法的Entity Framework Core。将更改保存到一个实体,该实体的相关对象之一发生更改时,我遇到了此错误:

“实体类型'Bird'的属性'BirdId'是键的一部分,因此无法进行修改或将其标记为已修改。要使用标识的外键更改现有实体的主体,请先删除依赖项并调用'然后,SaveChanges将依赖项与新的主体相关联。“

将更改保存到类型为Observation的实体并更新为相关的Bird对象时,我遇到错误。我包括以下模型设置:

public class Observation
{
    [Key]
    public int ObservationId { get; set; }

    // other properties...

    public int BirdId { get; set; }

    public Bird Bird { get; set; }
}

Bird类看起来像这样:

public class Bird
{
    [Key]
    public int BirdId { get; set; }

    // other properties...

    public ICollection<Observation> Observations { get; set; }
}

我仅依靠EF Core模型约定(我没有在OnModelCreating方法中添加代码),通过EF迁移,可以这样建立数据库:

        migrationBuilder.CreateTable(
            name: "Observation",
            columns: table => new
            {
                ObservationId = table.Column<int>(nullable: false)
                    .Annotation("SqlServer:Identity", "1, 1"),
                BirdId = table.Column<int>(nullable: false),
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_Observation", x => x.ObservationId);
                table.ForeignKey(
                    name: "FK_Observation_Bird_BirdId",
                    column: x => x.BirdId,
                    principalTable: "Bird",
                    principalColumn: "BirdId",
                    onDelete: ReferentialAction.Cascade);
            });

我是否正确设置了模型?

我用于保存更新的观察值的代码如下:

            observation.BirdId = model.Bird.BirdId;
            var bird = await _birdRepository.GetBirdAsync(model.Bird.BirdId);
            observation.Bird = bird;

            observation.LastUpdateDate = _systemClock.GetNow;

            await _unitOfWork.CompleteAsync();

但是,我认为问题在于在模型中建立关系的方式。任何人都可以阐明这个问题吗?

1 个答案:

答案 0 :(得分:1)

observation.Bird按照惯例链接到observation.BirdId。您不应同时更改两者,通常建议仅更改导航属性。 我将假设model是一个视图模型,因此您不能直接使用其Bird,但基本上可以省去第一行代码,而只需设置observation.Bird

在这种情况下,EF感到困惑,因为您尝试两次更改关系。