ObjectStateManager中已存在具有相同键的对象.ObjectStateManager无法使用相同的键跟踪多个对象

Wil*_*Wil 59 entity-framework

基本上,我有一个表格,其中包含公司的一些属性.这是"主"表,它们的ID在许多其他表中使用.我基本上通过这种方法找到他们的ID:

private Company currentcompany()
    {
        Company cuco = db.Companies.Single(x => x.username == User.Identity.Name);
        return cuco;
    }
Run Code Online (Sandbox Code Playgroud)

我需要让用户能够更新存储在此表中的各种有关自己的详细信息,我做得非常好 - 但是,我注意到了一个很大的安全漏洞!

在Firefox上使用篡改数据(我想象Fidler /许多其他人),我可以轻松更改隐藏的ID并修改其他公司的详细信息.

为了阻止这种情况,我在修改操作中添加了以下行:

        Company cuco = currentcompany();

        if (company.id != cuco.id)
        {
            return Content("Security Error");
        }
Run Code Online (Sandbox Code Playgroud)

(仅供参考 - Company是代表公司的模型/ POCO,company本身就是表单数据.)

添加之后,如果我在表单数据中编辑ID,它会按预期工作并显示"安全错误",但是,如果没有错误我继续,我会在问题中得到错误.

"ObjectStateManager中已存在具有相同键的对象.ObjectStateManager无法使用相同的键跟踪多个对象."

我相信这是因为EF以某种方式检测并保持第一次数据拉动,但我不确定如何纠正它.

有什么建议?

编辑 - 更新 -

如果你能理解我想要实现的目标,那么有更好的解决方法吗?

Lad*_*nka 150

如果从上下文加载实体,则无法再次使用相同的键附加实体.第一个实体仍保留在内部上下文缓存中,并且上下文只能容纳一个具有每个类型给定键值的实例(它被称为身份映射,在其他情况下将其描述).

您可以通过分离前实例来解决它,但您不必这样做.如果您只需要保存新值,可以使用:

  • ObjectContext API: context.YourEntitySet.ApplyCurrentValues(newEntity);
  • DbContext API: context.Entry(oldEntity).CurrentValues.SetValues(newEntity);

  • 你摇滚......我想你已经在我的网站上找到了一个很好的答案!我只是有点厌倦了问了这么多EF问题,觉得我应该知道更好!除了奇怪的博客和问题,我找不到很多资源,只是想知道你是否可以推荐任何可以帮助我的东西?...另外,对于这个实际问题,你会说做防伪标记就足够了/在这种情况下你会做什么?我总是认为客户的任何东西都应该被视为 (6认同)

Ser*_*gan 5

如果您不知道如何oldEntity根据Ladislav 找到,请给您一点帮助:

var entityKey = context.NewEntitySet.Create().GetType().GetProperty("Id").GetValue(newEntity);

factory.Entry(context.Set<NewEntityType>().Find(entityKey)).CurrentValues.SetValues(newEntity);
Run Code Online (Sandbox Code Playgroud)