向DbSet<T>添加实体未标记为Added且未提交问题求助(附示例仓库)
解决EF Core中添加实体未标记为Added的问题
结合你给出的实体定义和DbContext配置,我能定位到问题的核心——你用阴影属性PersonId作为Attributes的主键,但配置和实体添加的方式没匹配上,导致EF Core无法正确识别这是一个需要新增的实体。下面一步步给你拆解问题和解决办法:
问题出在哪?
你的Attributes实体依赖阴影属性PersonId作为主键,同时关联了Person导航属性。这种一对一的配置(主键兼外键)需要满足两个条件才能让EF Core标记实体为Added:
- 主键(也就是
PersonId)必须有一个非默认值(int类型不能是0); - 要么正确关联
Person导航属性,要么手动设置PersonId的值,让EF Core能识别这是一个合法的新实体。
如果这两个条件没满足,EF Core会认为这个实体状态不明确,不会标记为Added,自然无法提交到数据库。
可行的解决方案
方案1:手动设置阴影属性的值
如果你想继续用阴影属性,添加实体时需要显式给PersonId赋值,让EF Core确认这是一个有效实体:
// 先创建并添加Person(如果数据库里还没有这个Person的话) var newPerson = new Person { Id = 1, Name = "Marcus" }; context.Persons.Add(newPerson); // 创建Attributes实体 var personAttributes = new Attributes { Attribs = "你的属性内容" }; // 手动设置阴影属性PersonId的值 context.Entry(personAttributes).Property("PersonId").CurrentValue = newPerson.Id; // 现在添加就能被标记为Added了 context.Attributes.Add(personAttributes); context.SaveChanges();
方案2:完善一对一关系的配置
你当前的配置只设置了阴影属性和主键,但没明确关联导航属性的关系。修改OnModelCreating的配置,让EF Core能通过导航属性自动追踪状态:
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // 明确Attributes和Person的一对一关系,指定外键为阴影属性PersonId modelBuilder.Entity<Attributes>() .HasOne(a => a.Person) .WithOne() // 如果Person实体没有对应的Attributes导航属性,就用空的WithOne() .HasForeignKey<Attributes>("PersonId"); // 继续设置主键为PersonId modelBuilder.Entity<Attributes>() .HasKey("PersonId"); }
之后添加实体时,只要正确关联Person导航属性,EF Core会自动处理主键和状态:
var newPerson = new Person { Id = 1, Name = "Marcus" }; context.Persons.Add(newPerson); var personAttributes = new Attributes { Person = newPerson, Attribs = "你的属性内容" }; context.Attributes.Add(personAttributes); context.SaveChanges();
方案3:把PersonId改成显式属性(最直观的方式)
如果不想折腾阴影属性,直接给Attributes加上显式的PersonId属性,这样状态追踪会更清晰:
public class Attributes { public int PersonId { get; set; } // 显式主键+外键 public Person Person { get; set; } public string Attribs { get; set; } }
然后简化配置:
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<Attributes>() .HasKey(a => a.PersonId); modelBuilder.Entity<Attributes>() .HasOne(a => a.Person) .WithOne() .HasForeignKey<Attributes>(a => a.PersonId); }
添加实体时直接赋值PersonId就行,完全不用考虑阴影属性的问题:
var personAttributes = new Attributes { PersonId = 1, Attribs = "你的属性内容" }; context.Attributes.Add(personAttributes); context.SaveChanges();
最后提醒一下
- 用阴影属性当主键时,一定要确保它的值不是默认值(比如int的0),否则EF Core会觉得这是个未初始化的实体,不会标记为Added;
- 这种一对一的关联,对应的
Person实体要么已经在数据库里存在,要么和Attributes一起被添加到上下文,不然会触发外键约束错误哦。
内容的提问来源于stack exchange,提问作者MarcusK
相关产品推荐
相关产品推荐

