J.P*_*rge 6 many-to-many ef-code-first asp.net-web-api entity-framework-5
我正在尝试Customer使用ASP.NET Web API和Entity Framework 5代码优先更新我的数据库,但它无法正常工作.我的实体看起来像这样:
public class CustomerModel
{
public int Id { get; set; }
public string Name { get; set; }
// More fields
public ICollection<CustomerTypeModel> CustomerTypes { get; set; }
}
public class CustomerTypeModel
{
public int Id { get; set; }
public string Type { get; set; }
[JsonIgnore]
public ICollection<CustomerModel> Customers { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
没有什么特别的.我已经构建了一个Web界面,用户可以通过提供名称和检查一个或多个客户类型来添加客户.点击提交按钮时,数据将发送到我的Web API方法:
public void Put([FromBody]CustomerModel customer)
{
using (var context = new MyContext())
{
context.Customers.Attach(customer);
context.Entry(customer).State = EntityState.Modified;
context.SaveChanges();
}
}
Run Code Online (Sandbox Code Playgroud)
这会更新客户字段,但会忽略相关的客户类型.传入的customer对象确实包含一个CustomerTypes应与之关联的列表:
[0] => { Id: 1, Type: "Finance", Customers: Null },
[1] => { Id: 2, Type: "Insurance", Customers: Null }
[2] => { Id: 3, Type: "Electronics", Customers: Null }
Run Code Online (Sandbox Code Playgroud)
但是,EF不是查看此列表并添加/删除关联实体,而是忽略它.忽略新关联,即使应删除现有关联,也会保留现有关联.
将客户插入数据库时遇到了类似的问题,当我将这些实体的状态调整为时,这个问题已得到解决EntityState.Unchanged.当然,我尝试在我的更新场景中应用同样的魔法修复:
public void Put([FromBody]CustomerModel customer)
{
using (var context = new MyContext())
{
foreach (var customertype in customer.CustomerTypes)
{
context.Entry(customertype).State = EntityState.Unchanged;
}
context.Customers.Attach(customer);
context.Entry(customer).State = EntityState.Modified;
context.SaveChanges();
}
}
Run Code Online (Sandbox Code Playgroud)
但EF继续显示相同的行为.
有想法该怎么解决这个吗?或者我应该只是手动清除列表CustomerTypes然后手动添加它们?
提前致谢.
J.P
Sla*_*uma 10
仅通过设置实体状态无法真正解决这个问题.您必须首先从数据库加载客户,包括其所有当前类型,然后根据已发布客户的更新类型集合从已加载客户中删除类型或添加类型.更改跟踪将完成剩余工作以从连接表中删除条目或插入新条目:
public void Put([FromBody]CustomerModel customer)
{
using (var context = new MyContext())
{
var customerInDb = context.Customers.Include(c => c.CustomerTypes)
.Single(c => c.Id == customer.Id);
// Updates the Name property
context.Entry(customerInDb).CurrentValues.SetValues(customer);
// Remove types
foreach (var typeInDb in customerInDb.CustomerTypes.ToList())
if (!customer.CustomerTypes.Any(t => t.Id == typeInDb.Id))
customerInDb.CustomerTypes.Remove(typeInDb);
// Add new types
foreach (var type in customer.CustomerTypes)
if (!customerInDb.CustomerTypes.Any(t => t.Id == type.Id))
{
context.CustomerTypes.Attach(type);
customerInDb.CustomerTypes.Add(type);
}
context.SaveChanges();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5029 次 |
| 最近记录: |