C#上下文当前没有跟踪实体错误APi。关于更新方法

时间:2018-04-13 09:54:48

标签: c# asp.net odata owin

我是c#的新手,我正在使用OData和Owinselfhost问题是当我尝试对我的对象进行更新总是得到这个错误时msg

The context is not currently tracking the entity

enter image description here

我的控制器

    [HttpPut]
    [Route()]
    // PUT api/people/5 
    public IHttpActionResult Put([FromBody]Person value)
    {
        Console.WriteLine("Value updated " + value.LastName);
        var result = api.updatePerson(value);
        if (result == false)
            return BadRequest("An error occurred");
        return Ok("Person updated");
    }

API服务

 public bool updatePerson(Person p)
        {
            try
            {
                var ctx = GetAppControlContext();
                Person person = new Person();
                person = ctx.People.Where(ps => ps.Id == p.Id).SingleOrDefault();
                if (person != null)
                {
                    //person.FirstName = p.FirstName;
                    person = p;

                    Console.WriteLine("Name" + person.FirstName);                    
                    ctx.UpdateObject(person); 
                    ctx.SaveChanges();
                }

                Console.WriteLine("person updated");
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return false;
            }
        }

PS 它只有在我按字段分配给人员时才有效

 public bool updatePerson(Person p)
        {
            try
            {
                var ctx = GetAppControlContext();
                Person person = new Person();
                person = ctx.People.Where(ps => ps.Id == p.Id).SingleOrDefault();
                if (person != null)
                {
                  person.FirstName = p.FirstName;
                  person.LastName= p.LastName;
                  person.age= p.age;

                    Console.WriteLine("Name" + person.FirstName);                    
                    ctx.UpdateObject(person); 
                    ctx.SaveChanges();
                }

                Console.WriteLine("person updated");
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return false;
            }
        }

这对我来说不实用,因为我有几个领域!

AppConrolContext

    public AppControlContext GetAppControlContext()
    {
        var appContext = new AppControlContext(ServerAppControl)
        {
            Credentials = new NetworkCredential(_user, _password)
        };

        return appContext;
    }

2 个答案:

答案 0 :(得分:0)

你说得对,只有你单独分配每个字段并且就是它的方式,你的代码才有效。因为Person是参考类型。

您有两个Personpperson的实例,这些变量只是指向您实例的指针。当你写person = p;时,两个指针都指向同一个实例,而你的上下文没有跟踪它。

所以你需要分配每个字段,但是如果你有很多字段,你可以使用AutoMapper来简化你的工作。

答案 1 :(得分:0)

您也可以使用context.Entry(Object).State = System.Data.Entity.EntityState.Modified;

在你的情况下你有ctx作为Context所以 (阅读评论解释)

public bool updatePerson(Person p)
{
  try
    {
      var ctx = GetAppControlContext();
      //if it exists then we can change the state to modified
      if (ctx.People.Any(ps => ps.Id == p.Id))
      {
        //This will attach the entity to the context
        //Will also mark it so it will be saved in SaveChanges();
        ctx.Entry(p).State = System.Data.Entity.EntityState.Modified;
        ctx.SaveChanges();
        Console.WriteLine("person updated");
        return true;
      }

    }catch (Exception ex)
    {
      Console.WriteLine(ex.ToString());
      return false;
    }
  return false;
}

修改

Link进一步解释,更多国家解释。