Fra*_*sco 5 ef-code-first sql-server-ce-4 entity-framework-4.1
我首先在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; }
}
Run Code Online (Sandbox Code Playgroud)
和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);
}
}
Run Code Online (Sandbox Code Playgroud)
同时在代码中我需要更新客户的整个ContactPerson集合.
List<ContactPersons> modifiedContactPersons;
Customer customer = MyDB.Customers.Find(ID);
customer.ContactPersons = modifiedContactPersons;
Run Code Online (Sandbox Code Playgroud)
当我调用MyDB.SaveChanges()时,我得到以下异常:
保存不公开其关系的外键属性的实体时发生错误.EntityEntries属性将返回null,因为无法将单个实体标识为异常的来源.通过在实体类型中公开外键属性,可以更轻松地在保存时处理异常.有关详细信息,请参阅InnerException.
与InnerException:
来自'Customer_ContactPersons'AssociationSet的关系处于'已删除'状态.给定多重约束,相应的'Customer_ContactPersons_Target'也必须处于'已删除'状态.
我明白这意味着什么,但我不能自己解决问题.有什么建议?
这里的问题是:
customer.ContactPersons = modifiedContactPersons;
Run Code Online (Sandbox Code Playgroud)
它用新的相关联系人名单替换旧的相关联系人名单,并进行两项操作:
Deleted Added第一个操作是一个问题,因为删除关系不会删除相关实体,因此您最终ContactPerson与任何内容无关,Customer并且您的映射不允许它(FK不可为空).
解决此问题取决于您尝试实现的要求.如果您确实要首先删除所有相关人员,则必须在分配新列表之前手动将每个人员的状态设置为已删除.如果您想更新现有人员,则根本不应该这样做.您应该迭代与客户相关的人员并从新列表中修改他们的数据.为什么?因为:
ContractPerson则无法将其删除.此外,如果您ContractPerson在Id某处使用它并且如果它是自动生成的,则在删除原始记录后它将不再存在.