我使用实体框架迁移(在自动迁移模式下)。一切都很好,但是我有一个问题:
有多对多关系时应如何播种数据?
例如,我有两个模型类:
public class Parcel
{
public int Id { get; set; }
public string Description { get; set; }
public double Weight { get; set; }
public virtual ICollection<BuyingItem> Items { get; set; }
}
public class BuyingItem
{
public int Id { get; set; }
public decimal Price { get; set; }
public virtual ICollection<Parcel> Parcels { get; set; }
}
我了解如何播种简单数据(用于PaymentSystem类)和一对多关系,但是我应该在
Seed
方法中编写什么代码来生成Parcel
和BuyingItem
的某些实例?我的意思是使用DbContext.AddOrUpdate()
,因为我不想每次运行Update-Database
时都重复数据。protected override void Seed(ParcelDbContext context)
{
context.AddOrUpdate(ps => ps.Id,
new PaymentSystem { Id = 1, Name = "Visa" },
new PaymentSystem { Id = 2, Name = "PayPal" },
new PaymentSystem { Id = 3, Name = "Cash" });
}
protected override void Seed(Context context)
{
base.Seed(context);
// This will create Parcel, BuyingItems and relations only once
context.AddOrUpdate(new Parcel()
{
Id = 1,
Description = "Test",
Items = new List<BuyingItem>
{
new BuyingItem() { Id = 1, Price = 10M },
new BuyingItem() { Id = 2, Price = 20M }
}
});
context.SaveChanges();
}
这段代码创建了
Parcel
,BuyingItems
及其关系,但是如果我在另一个BuyingItem
中需要相同的Parcel
(它们之间存在多对多关系),我会在第二个包裹中重复此代码-将在数据库中复制BuyingItems
(尽管我设置了相同的Id
)。例:
protected override void Seed(Context context)
{
base.Seed(context);
context.AddOrUpdate(new Parcel()
{
Id = 1,
Description = "Test",
Items = new List<BuyingItem>
{
new BuyingItem() { Id = 1, Price = 10M },
new BuyingItem() { Id = 2, Price = 20M }
}
});
context.AddOrUpdate(new Parcel()
{
Id = 2,
Description = "Test2",
Items = new List<BuyingItem>
{
new BuyingItem() { Id = 1, Price = 10M },
new BuyingItem() { Id = 2, Price = 20M }
}
});
context.SaveChanges();
}
如何在不同的
BuyingItem
中添加相同的Parcel
? 最佳答案
您必须以与在任何EF代码中建立多对多关系相同的方式填充多对多关系:
protected override void Seed(Context context)
{
base.Seed(context);
// This will create Parcel, BuyingItems and relations only once
context.AddOrUpdate(new Parcel()
{
Id = 1,
Description = "Test",
Items = new List<BuyingItem>
{
new BuyingItem() { Id = 1, Price = 10M },
new BuyingItem() { Id = 2, Price = 20M }
}
});
context.SaveChanges();
}
指定将在数据库中使用的
Id
是至关重要的,否则每个Update-Database
都会创建新记录。AddOrUpdate
不支持以任何方式更改关系,因此您不能在下一次迁移中使用它来添加或删除关系。如果需要,您必须手动删除关联,方法是将Parcel
装入BuyingItems
并在导航集合上调用Remove
或Add
来中断或添加新的关联。