我有一个使用MSVS 2019的简单的“ ContactsList” ASP.Net Core Web(REST)应用程序,.Net Core 3.0,MSSQL LocalDB。
我的“联系人”实体包含“注释”列表。
当我创建一个已经包含一个或多个便笺的新联系人时,一切正常。 EF将注释自动插入注释表中。
但是当我尝试更新一个联系人时,EF似乎无视“注释”。
问:对于“更新”,我是否需要在控制器中编写代码以自己明确更新笔记? 还是我在做“错误”的事情,以至于EF无法“自动”进行应有的更新?
Models / 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; }
}
Models / 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应该自动处理“更新”笔记吗,还是需要在控制器中手动编码更新?
答案 0 :(得分:1)
实体框架核心会忽略关系,除非您在查询中明确包含它们。
_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();