Bru*_*oLM 3 c# asp.net-mvc entity-framework owin asp.net-mvc-5
我有一个简单的模型粘合剂:
public class PersonBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
// ...
// id = routevalues[ id ]
var db = controllerContext.HttpContext.GetOwinContext().Get<ApplicationDbContext>();
return db.Set<Person>().FirstOrDefault(o => o.Id == id);
}
}
Run Code Online (Sandbox Code Playgroud)
它工作正常.这里举例如下:
public ActionResult Edit(Person entity, int? id)
{
if (entity == null && id.HasValue)
throw new HttpException(404, "Person not found.");
return View(person);
}
Run Code Online (Sandbox Code Playgroud)
问题是当我尝试将其保存在数据库中时:
// DbContext = HttpContext.GetOwinContext().Get<ApplicationDbContext>()
[HttpPost]
public async Task<ActionResult> Edit(Person entity, int? id)
{
if (entity == null && id.HasValue)
throw new HttpException(404, "Person not found.");
if (ModelState.IsValid)
{
// WORKS when inserting a new person to the database
if (!id.HasValue)
DbContext.People.Add(entity);
else
{
// if I try to attach I get an error: see bellow
// if I don't attach, it does nothing
}
await DbContext.SaveChangesAsync();
}
return View(entity);
}
Run Code Online (Sandbox Code Playgroud)
附加错误:
System.InvalidOperationException:附加类型为"..Person"的实体失败,因为同一类型的另一个实体已具有相同的主键值.如果图中的任何实体具有冲突的键值,则在使用"附加"方法或将实体的状态设置为"未更改"或"已修改"时,可能会发生这种情况.这可能是因为某些实体是新的并且尚未收到数据库生成的键值.在这种情况下,使用"添加"方法或"已添加"实体状态来跟踪图形,然后根据需要将非新实体的状态设置为"未更改"或"已修改".
实体状态显示为Detached在控制器操作中运行时:
DbContext.Entry(entity).State
Run Code Online (Sandbox Code Playgroud)
为什么会这样?我该怎么办呢?是不是可以使用粘合剂?
在执行附加之前,如果分离现有实体,该怎么办?类似的东西:(没有经过测试 - 对不起,这是基于一个旧项目中的一些代码,我们不得不因为不同的原因做了类似的事情,但希望能提出这个想法)
if (!id.HasValue)
DbContext.People.Add(entity);
else
{
var attachedEntity = DbContext.People.Find(id);
if (attachedEntity != null && DbContext.Entry(attachedEntity).State != EntityState.Detached)
{
DbContext.Entry(attachedEntity).State = EntityState.Detached;
// You may need to recursively detach child entities here if any
}
DbContext.People.Attach(entity);
DbContext.Entry(entity).State = EntityState.Modified;
}
Run Code Online (Sandbox Code Playgroud)
编辑:
由于主要问题似乎是你的DbContext的实例是不同的,这是有道理的,因为文档IOwinContext.Get<T>说"从OWIN环境获取一个值,或者如果不存在则返回默认值(T)".
http://msdn.microsoft.com/en-us/library/dn270607(v=vs.113).aspx
你能在某个地方(我没有使用OWIN那么不确定最佳位置 - 但我猜你的管道的开头)调用IOwinContext.Set<ApplicationDbContext>并传递一个新的DbContext,以便你的2调用HttpContext.GetOwinContext ().Get()共享同一个实例?
| 归档时间: |
|
| 查看次数: |
1025 次 |
| 最近记录: |