让我们想象一下这个EF模型:
public class Person
{
[Key]
public int Id {get; set; }
public string Name { get; set; }
public string FirstName { get; set; }
public int Age { get; set; }
[InverseProperty("Person")]
public ICollection<Address> Addresses { get; set; }
}
public class Address
{
[Key]
public int Id {get; set; }
public int Number { get; set; }
public string Street { get; set; }
public string City { get; set; }
public int PersonId { get; set; }
[ForeignKey("PersonId")]
[InverseProperty("Adresses")]
public Person Person { get; set; }
}
一个人可以有多个地址.
我的应用程序中有一个页面,可以同时管理“人”和“地址”.在此页面中,我可以在一个Breeze saveChanges()调用中创建一个Person和许多地址.
它工作正常,除非当我尝试修改Person属性并同时添加新地址时.
这是Breeze Web API控制器正在接收的那种JObject:
{
"entities": [
{
"Id": -1,
"PersonId": 3,
"City": "Seattle",
"Street": "Main Av",
"Number": 1540,
"entityAspect": {
"entityTypeName": "Address:#MyApp.Models",
"defaultResourceName": "Addresses",
"entityState": "Added",
"originalValuesMap": {},
"autoGeneratedKey": {
"propertyName": "Id",
"autoGeneratedKeyType": "Identity"
}
}
},
{
"Id": 3,
"Name": "Doe",
"FirstName": "John",
"Age": 32,
"entityAspect": {
"entityTypeName": "Person:#MyApp.Models",
"defaultResourceName": "Persons",
"entityState": "Modified",
"originalValuesMap": {
"FirstName": "William"
},
"autoGeneratedKey": {
"propertyName": "Id",
"autoGeneratedKeyType": "Identity"
}
}
}
],
"saveOptions": {}
}
在服务器端调用contextProvider.SaveChanges()时,EF抱怨并拒绝接受我的更改:
因为对象的键值与ObjectStateManager中的另一个对象冲突,所以AcceptChanges无法继续.在调用AcceptChanges之前,请确保键值是唯一的.
我不知道发生了什么,但是Breeze保存这些实体的方式似乎导致了Entity Framework状态管理器中的重复实体.
有谁知道如何解决/解决这个问题?这是Breeze中的错误,还是我做得不正确?
顺便说一句,我正在使用Breeze 1.4.2和Entity Framework 5.0.0
解决方法:
我找到了问题的答案.
实际上,我在保存之前使用Breeze的BeforeSaveEntities委托执行了一些验证.问题是,如果在这些验证期间从DBContext检索实体,并且该实体稍后作为提交给Breeze控制器的JObject的一部分被保存,则会遇到问题.
我使用的解决方法是代替AfterSaveEntities挂钩执行这些验证,并告诉Breeze使用事务.