gpt4 book ai didi

c# - 如何将 ModelBinders 与存储在 OwinContext 中的 DbContext 一起使用?

转载 作者:行者123 更新时间:2023-11-30 15:28:19 27 4
gpt4 key购买 nike

我有一个简单的模型 Binder :

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);
}
}

而且效果很好。这里例如:

public ActionResult Edit(Person entity, int? id)
{
if (entity == null && id.HasValue)
throw new HttpException(404, "Person not found.");

return View(person);
}

问题是当我尝试将它保存在数据库中时:

// 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);
}

附加错误:

System.InvalidOperationException: Attaching an entity of type '..Person' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.

当我在 Controller 操作中运行它时,实体状态显示为 Detached:

DbContext.Entry(entity).State

为什么会这样?我该如何解决?不能为此使用 Binder 吗?

最佳答案

在执行附加之前,如果您分离现有实体会怎样?类似于:(未测试 - 抱歉,这是基于旧项目中的一些代码,我们出于不同的原因不得不做类似的事情,但希望能给出想法)

    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;
}

编辑:

因为主要问题似乎是您的 DbContext 实例不同,考虑到 IOwinContext.Get<T> 的文档,这是有道理的说“从 OWIN 环境获取值,如果不存在则返回默认值 (T)。”

http://msdn.microsoft.com/en-us/library/dn270607(v=vs.113).aspx

,你能不能在某个地方(我没有经常使用 OWIN,所以不确定最好的地方在哪里 - 但我猜在你的管道的开头)调用 IOwinContext.Set<ApplicationDbContext>并向其传递一个新的 DbContext,以便您对 HttpContext.GetOwinContext().Get() 的 2 个调用共享同一个实例?

关于c# - 如何将 ModelBinders 与存储在 OwinContext 中的 DbContext 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25955652/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com