Web API 2和EF附加问题

本文关键字:问题 EF API Web | 更新日期: 2023-09-27 18:05:23

我有一个使用web api 2开发的web服务,它使用ef 6将数据保存回数据库。

数据结构如下:

public class User
{
    [Key]
    public int UserId { get; set; }
    public string FullName { get; set; }
    public string Email { get; set; }
}
public class Contact
{
    [Key]
    public int ContactId { get; set; }
    public string ContactName { get; set; }
    public int CreatedById { get; set; }
    [ForeignKey("CreatedById")]
    public User CreatedBy { get; set; }
    public int ModifiedById { get; set; }
    [ForeignKey("ModifiedById")]
    public User ModifiedBy { get; set; }
}
public class Note
{
    [Key]
    public int NoteId { get; set; }
    public string Notes { get; set; }
    public int ContactId { get; set; }
    [ForeignKey("ContactId")]
    public Contact Contact { get; set; }
    public int CreatedById { get; set; }
    [ForeignKey("CreatedById")]
    public User CreatedBy { get; set; }
    public int ModifiedById { get; set; }
    [ForeignKey("ModifiedById")]
    public User ModifiedBy { get; set; }
}

我使用锅炉板代码来尝试保存修改,以便在web api中注释如下

    // PUT: api/Notes/5
    [ResponseType(typeof(void))]
    public IHttpActionResult PutNote(int id, Note note)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }
        if (id != note.NoteId)
        {
            return BadRequest();
        }
        db.Entry(note).State = EntityState.Modified;
        try
        {
            db.SaveChanges();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!AttachmentExists(id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return StatusCode(HttpStatusCode.NoContent);
    }

然而,当修改entitystate的那行被执行时,我得到了以下异常:

附加类型为"User"的实体失败,因为另一个相同类型的实体已经具有相同的主键值。当使用"Attach"方法或将实体的状态设置为"Unchanged"或"Modified"(如果图中的任何实体具有冲突的键值)时,可能会发生这种情况。这可能是因为一些实体是新的,还没有接收到数据库生成的键值。在这种情况下,使用"添加"方法或"添加"实体状态来跟踪图形,然后根据需要将非新实体的状态设置为"未更改"或"修改"。

我发现这令人费解,因为我没有手动附加任何实体,并且db.ChangeTracker.Entries()此时为空。我本以为EF会处理同一个实体可以在树中被引用多次的事实。

有人遇到过这个问题吗?有人有解决方案吗?

提前感谢,

尼尔。

Web API 2和EF附加问题

我认为问题的一部分是有可能你的笔记模型从未正确加载到EF的对象图中进行跟踪。

试试下面的伪代码:

// PUT: api/Notes/5
[ResponseType(typeof(void))]
public IHttpActionResult PutNote(int id, Note note)
{
    if (!ModelState.IsValid)
        return BadRequest(ModelState);
    if (id != note.NoteId)
        return BadRequest();
    //Not sure how you're setup, but have EF fetch the note you want
    //to modify from the DB. It is now aware of it and tracking changes.
    var model = _getNoteModelFromDbById(note.NoteId);
    //Now that you have the model from the DB you can map the properties 
    //of the incoming note to your model. Bellow is just a basic example.         
    //I recommend you look into a library called Automapper later on. 
     model.Title = note.Title;
     model.Description = note.Description;
     model.Status = note.Status;
    db.Entry(model).State = EntityState.Modified;
    try
    {
        db.SaveChanges();
    }
    catch (DbUpdateConcurrencyException)
    {
        if (!AttachmentExists(id))
            return NotFound();
        else
            throw;
    }
    return StatusCode(HttpStatusCode.NoContent);
}