C# 如何首先使用EF代码插入对象图

C# 如何首先使用EF代码插入对象图,c#,winforms,ef-code-first,C#,Winforms,Ef Code First,我无法找到插入对象图失败的原因 我有一个1..N流记录的对象图-升级。 当我创建一个新的促销记录时,我还需要创建一个相关的流程记录 这就是我尝试的方法 var newpromo = new Promotion(); var newflow = new Flow(); newpromo.Flow.Add(newflow); //i thought this should enough to tell EF that newflow's PromotionId //should be t

我无法找到插入对象图失败的原因

我有一个1..N流记录的对象图-升级。 当我创建一个新的促销记录时,我还需要创建一个相关的流程记录

这就是我尝试的方法

var newpromo = new Promotion();
var newflow = new Flow();    
newpromo.Flow.Add(newflow); 

//i thought this should enough to tell EF that newflow's PromotionId
//should be the newly inserted nepromo's Id
newflow.Promotion = newpromo;  
//...
db.Promotions.Attach(newpromo);
db.Entry(newflow).State = System.Data.Entity.EntityState.Added;
但是当我调用db.SaveChanges()时,我收到了这个错误

{"The INSERT statement conflicted with the FOREIGN KEY constraint 
\"FK_PromotionFlow_Promotions\". The conflict occurred in database \"RepositoryDb\", 
table\"dbo.Promotions\", column 'Id'.\r\nThe statement has been terminated."}
问题的原因是什么?

定义: 1) 这是升级和流程POCO类定义

class Promotion
{
    public Int32 Id { get; set; }
    public List<PromotionFlow> Flow { get; set; }
    //...other fields
}

class PromotionFlow
{
    public Int32 Id { get; set; }
    public Int32 PromotionId { get; set; }
    public Promotion Promotion { get; set; }
    //other fields
}

尝试先保存促销,然后将流添加到促销并保存流(或促销)


听起来您的promo没有用于流的ID,因为promo尚未插入数据库。

我找到了问题的原因。。。我需要将对象图父项(即升级对象)的状态设置为“已添加”(附加到上下文是不够的,因为这是一个新对象)

在将新的促销对象附加到上下文后,我丢失了此行

db.Entry(newpromotion).State = System.Data.Entity.EntityState.Added; //<==THIS ROW
//... dealing with the child (flow) entry states
db.SaveChanges();

另外,现在它在一个db.SaveChanges()调用中插入所有图形,在插入流对象之前不需要插入升级

但是如果我插入一个对象图形,这不应该是Entity Framework解决的问题吗?插入父项,然后检索父项id,并使用检索到的父项id插入子记录?我尝试在flow之前插入promo,但得到了相同的错误-谢谢,Nathan,它帮助我找到了真正的问题->我没有设置DbContext.Entry(newpromo).State=Added;嗯,实际上看起来DbSet.Add方法的工作原理与DbContext.Entry(entity.State=…EntityState.Added相同,因此我必须检查所有相关的实体状态并设置适当的EntityState(如果我不希望将这些实体插入数据库中的话)
CONSTRAINT [FK_PromotionFlow_Promotions] FOREIGN KEY ([PromotionId]) REFERENCES [dbo].[Promotions] ([Id])
//(...)
db.Promotions.Attach(newpromo);
db.Entry(newpromotion).State = System.Data.Entity.EntityState.Added; //<==THIS ROW
//... dealing with the child (flow) entry states
db.SaveChanges();
db.Promotions.Add(newpromo);