EF Core 2.0中关联记录更新问题求助
解决更新SchoolGovernor关联EthnicOrigin时的主键修改报错问题
嘿,这个问题我太熟了——本质是EF处理关联实体的逻辑误区,咱们把问题拆解开,一步步解决:
问题根源
EthnicOrigin是查找表,它的Id是主键,EF会默认把主键标记为不可修改的只读属性。当你尝试直接修改关联的EthnicOrigin实体的Id时,EF会判定你要修改主键,直接抛出那个报错;如果没做特殊处理就更新,大概率是EF没追踪到关联关系的变化,所以根本没生成更新语句。
正确的更新姿势
你要做的不是修改EthnicOrigin实体本身,而是修改SchoolGovernor和EthnicOrigin的关联关系,下面分两种常见场景给你代码示例:
场景1:你的模型有显式外键属性(推荐)
如果你的实体类定义了EthnicOriginId外键,直接修改这个字段是最高效的:
先看实体结构:
public class SchoolGovernor { public int Id { get; set; } public string FullName { get; set; } // 显式外键属性 public int EthnicOriginId { get; set; } // 导航属性 public virtual EthnicOrigin EthnicOrigin { get; set; } } public class EthnicOrigin { public int Id { get; set; } public string OriginName { get; set; } }
更新代码:
using (var dbContext = new YourSchoolDbContext()) { // 找到要更新的理事 var targetGovernor = dbContext.SchoolGovernors.Find(yourGovernorId); if (targetGovernor != null) { // 直接设置新的种族外键ID,EF会自动处理关联 targetGovernor.EthnicOriginId = newTargetEthnicOriginId; dbContext.SaveChanges(); } }
场景2:模型没有显式外键属性
如果你的模型只有导航属性,没有EthnicOriginId,那需要先把目标EthnicOrigin实体附加到EF的追踪上下文,再修改关联:
using (var dbContext = new YourSchoolDbContext()) { var targetGovernor = dbContext.SchoolGovernors.Find(yourGovernorId); if (targetGovernor != null) { // 创建目标种族的实例(只需要Id,因为是查找表) var newEthnicOrigin = new EthnicOrigin { Id = newTargetEthnicOriginId }; // 附加到上下文,告诉EF这个实体是已存在的,不要尝试新增 dbContext.EthnicOrigins.Attach(newEthnicOrigin); // 修改关联关系 targetGovernor.EthnicOrigin = newEthnicOrigin; dbContext.SaveChanges(); } }
避坑提醒
千万别犯这个错:直接修改关联实体的主键!比如下面这种写法肯定会报错:
// ❌ 错误示例!绝对不要这么写 targetGovernor.EthnicOrigin.Id = newTargetEthnicOriginId;
EF会把这个操作判定为修改EthnicOrigin实体的主键,而主键是不允许变更的,自然就抛出你看到的那个错误了。
总结一下:查找表的作用是存储固定选项,你要做的只是把理事关联到另一个已存在的种族记录上,而不是修改种族记录本身~
内容的提问来源于stack exchange,提问作者Paul Hepple
相关产品推荐
相关产品推荐

