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

时间:2014-03-06 16:22:25

标签: c# winforms ef-code-first

我找不到原因为什么我无法插入对象图

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

我尝试这样做

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)这是Promotion和Flow 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
}

2)我使用流畅的api

设置了映射
class PromotionMapping : EntityTypeConfiguration<Promotion>
{
    public PromotionMapping()
    {
        //Mapping both tables
        HasMany(x => x.Flow).WithRequired(x=>x.Promotion).HasForeignKey(x => x.PromotionId);
        //...other mapping 
    }
}

3)在数据库中,我将PromotionFlow.PromotionId列配置为Promotion.Id列的外键

CONSTRAINT [FK_PromotionFlow_Promotions] FOREIGN KEY ([PromotionId]) REFERENCES [dbo].[Promotions] ([Id])

2 个答案:

答案 0 :(得分:1)

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

听起来你的促销没有用于流程的ID,因为促销尚未插入数据库。

答案 1 :(得分:1)

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

//(...)
db.Promotions.Attach(newpromo);

在将新的Promotion对象附加到上下文后,我错过了这一行!

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

P.S。我没有使用DbContext.DbSet.Add()方法的原因是因为它为图中的所有对象设置了实体状态(并且我的一些对象引用了“设置”和“类别”类型数据,即我不打算再次插入)

db.Promotions.Add(newpromo);

P.S。现在它将所有图形插入到一个db.SaveChanges()调用中,在插入Flow对象之前无需插入Promotion