我首先在SQL ce 4.0中使用EF 4.1代码
我有两个班级
public class Customer
{
public int ID { get; set; }
public string CompanyName { get; set; }
public List<ContactPerson> ContactPersons { get; set; }
}
public class ContactPerson
{
public int ID { get; set; }
public string Name { get; set; }
}
和DbContext
public class MyDB : DbContext
{
public DbSet<ContactPerson> ContactPersons { get; set; }
public DbSet<Customer> Customers { get; set; }
public MyDB()
{
this.Configuration.LazyLoadingEnabled = true;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Customer>()
.HasMany(c => c.ContactPersons)
.WithRequired()
.WillCascadeOnDelete(true);
}
}
同时在代码中我需要更新客户的整个ContactPerson集合。
List<ContactPersons> modifiedContactPersons;
Customer customer = MyDB.Customers.Find(ID);
customer.ContactPersons = modifiedContactPersons;
当我调用MyDB.SaveChanges()时,我得到以下异常:
保存不公开外键的实体时发生错误 他们关系的属性。 EntityEntries属性将 返回null,因为无法将单个实体标识为源 例外。可以在保存时处理异常 通过在实体类型中公开外键属性更容易。看到 InnerException以获取详细信息。
使用InnerException:
来自'Customer_ContactPersons'AssociationSet的关系在 '已删除'状态。给定多重约束,相应的 'Customer_ContactPersons_Target'也必须处于'已删除'状态。
我明白这意味着什么,但我不能自己解决问题。 有什么建议吗?
答案 0 :(得分:8)
问题在于:
customer.ContactPersons = modifiedContactPersons;
它将新的相关联系人列表替换为新的相关联系人列表,并进行两项操作:
Deleted
Added
第一个操作是一个问题,因为删除关系不会删除相关实体,因此您最终得到的ContactPerson
与任何Customer
无关,并且您的映射不允许它(FK是不可空的。)
解决此问题取决于您尝试实现的要求。如果您确实要首先删除所有相关人员,则必须在分配新列表之前手动将每个人员的状态设置为已删除。如果您想更新现有人员,则根本不应该这样做。您应该迭代与客户相关的人员并从新列表中修改他们的数据。为什么?这是因为:
ContractPerson
的实体,则无法将其删除。此外,如果您在某处使用ContractPerson
的{{1}},并且如果它是自动生成的,则在您删除原始记录后它将不再存在。