实体框架核心:如何使用嵌套字段更新记录?

保罗4

我有一个简单的“ ContactsList” ASP.Net Core Web(REST)应用程序,.Net Core 3.0,使用MSVS 2019的MSSQL LocalDB。

我的“联系人”实体包含“注释”列表。

当我创建一个已经包含一个或多个便笺的新联系人时,一切正常。EF将注释自动插入注释表中。

但是,当我尝试更新联系人时,EF似乎无视“注释”。

问:对于“更新”,我是否需要在控制器中编写代码以自己明确更新笔记?还是我在做“错误”的事情,以至于EF无法“自动”进行应有的更新?

  • 型号/Contact.cs:

    public class Contact
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int ContactId { get; set; }
        public string Name { get; set; }
        public string EMail { get; set; }
        public string Phone1 { get; set; }
        public string Phone2 { get; set; }
        public string Address1 { get; set; }
        public string Address2 { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string Zip { get; set; }
        public List<Note> Notes { get; set; }
    }
    
  • 型号/Note.cs:

    public class Note
    {
        public Note()
        {
            this.Date = DateTime.Now; // Default value: local "now"
        }
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int NoteId { get; set; }
        public string Text { get; set; }
        public DateTime Date { get; set; }
        [ForeignKey("Contact")]
        public int ContactId { get; set; }
    }
    
  • Controllers / ContactsController.cs(POST起作用:如果联系人列表中有注释,它将添加它们):

    [HttpPost]
    public async Task<ActionResult<Contact>> PostContact(Contact contact)
    {
        _context.Contacts.Add(contact);
        await _context.SaveChangesAsync();
    
        //return CreatedAtAction("GetContact", new { id = contact.ContactId }, contact);
        return CreatedAtAction(nameof(GetContact), new { id = contact.ContactId }, contact);
    }
    
  • Controllers / ContactsController.cs(PUT似乎完全无视任何相关注释):

    [HttpPut("{id}")]
    public async Task<IActionResult> PutContact(int id, Contact contact)
    {
        if (id != contact.ContactId)
        {
            return BadRequest();
        }
    
        _context.Entry(contact).State = EntityState.Modified;
    
        try
        {
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!ContactExists(id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
    
        return NoContent();
    }
    

POST的SQL显示四个单独的INSERT:一个用于联系人,一个用于每个便笺。

用于PUT的SQL仅显示一个UPDATE:仅联系人;没有其他的。

调试器显示“注释”显然是控制器由PutContact()接收的“联系”记录的一部分。

问:EF应该自动处理“更新”笔记,还是需要在控制器中手动编码更新?

丹尼斯1679

除非您在查询中明确包含关系,否则Entity Framework Core会忽略关系。

_context.Entry(contact).State = EntityState.Modified;

上面一行的问题是,您没有指定相关数据已被修改,因此在查询中将忽略它。

所以你可以

  • 附加所有相关数据
  • 将相关数据的状态设置为 EntityState.Modified

或者你可以

  • 查询数据库中的对象并包含相关数据
  • 然后将联系人对象分配给该查询对象
 var dbContactObj = _context.Contacts.Include(x => x.Notes).First(x => x.Id == contact.Id);
 dbContactObj = contact;

 _context.SaveChangesAsync();

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章