我正在使用带有代码优先方法的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();
但是,我认为问题在于在模型中建立关系的方式。任何人都可以阐明这个问题吗?
答案 0 :(得分:1)
observation.Bird
按照惯例链接到observation.BirdId
。您不应同时更改两者,通常建议仅更改导航属性。
我将假设model
是一个视图模型,因此您不能直接使用其Bird,但基本上可以省去第一行代码,而只需设置observation.Bird
。
在这种情况下,EF感到困惑,因为您尝试两次更改关系。