使用Entity Framework Core更新相關數據

asp.net-core-webapi asp.net-web-api c# entity-framework-core

我用Entity Framework Core構建一個簡單的webapi。我正在使用模型和視圖模型來管理客戶端實際接收的數據。這是我創建的模型和視圖模型:

public class Team : BaseEntity
{
    [Key]
    public int TeamId { get; set; }
    [Required]
    public string TeamName { get; set; }
    public List<TeamAgent> TeamAgents { get; set; }
}

public class TeamViewModel
{
    [Required]
    public int TeamId { get; set; }
    [Required]
    public string TeamName { get; set; }
    [DataType(DataType.Date)]
    public DateTime DateCreated { get; set; }
    [DataType(DataType.Date)]
    public DateTime DateModified { get; set; }
    public List<TeamAgent> TeamAgents { get; set; }
}

public class TeamAgent : BaseEntity
{
    [Key]
    public int TeamAgentId { get; set; }
    [ForeignKey("Agent")]
    public int AgentId { get; set; }
    [JsonIgnore]
    public virtual Agent Agent { get; set; }
    [ForeignKey("Team")]
    public int TeamId { get; set; }
    [JsonIgnore]
    public virtual Team Team { get; set; }
    [Required]
    public string Token { get; set; }
}

public class TeamAgentViewModel
{
    [Required]
    public virtual AgentViewModel Agent { get; set; }
    [Required]
    public string Token { get; set; }
}

現在更新我在我的控制器中創建了一個Update方法:

[HttpPut("{id}")]
public async Task<IActionResult> Update(int id, [FromBody]TeamViewModel teamVM)
{
    if (ModelState.IsValid)
    {
        var team = await _context.Teams
                            .Include(t => t.TeamAgents)
                            .SingleOrDefaultAsync(c => c.TeamId == id);

        team.TeamName = teamVM.TeamName;

        // HOW TO HANDLE IF SOME TEAMAGENTS GOT ADDED OR REMOVED???

        _context.Teams.Update(team);
        await _context.SaveChangesAsync();

        return new NoContentResult();
    }
    return BadRequest(ModelState);
}

我讓自己陷入瞭如何更新連接到團隊的TeamAgent的問題。我嘗試和工作的一件事是刪除所有TeamAgent,然後每次更新Team數據時創建新的TeamAgent。就是這樣:

team.TeamAgents.Clear();
await _context.SaveChangesAsync();
team.TeamAgents.AddRange(teamVM.TeamAgents);

_context.Teams.Update(team);
await _context.SaveChangesAsync();

但這顯然不是很好的方法。使用Entity Framework Core更新相關項目的正確方法是什麼?

熱門答案

朱莉·勒曼(Julie Lerman)在2016年4月的文章“ 處理EF中的脫離實體狀態”一文中提到了這一點。如果您還沒有看過這篇文章,那麼值得一讀。遺憾的是,從EF Core 2.0開始,仍然沒有內置的方法來更新對像圖。

Julie的文章中提到的方法是通過向對象添加屬性並將狀態發送到客戶端來基本跟踪分離實體的狀態。客戶端可以修改狀態並將其發送回服務器,然後您當然可以使用該信息做正確的事情。

在我最近的項目中,我採取了稍微不同的方法,主要是因為到目前為止只有一個操作需要更新子集合。在我必須再次這樣做的時候,我可能會把朱莉的建議銘記於心並重構。

基本上它只是一個手動對像圖更新,看起來非常類似於你使用EF 6.0的方法。需要注意的一點是,現在使用EF Core,您只需調用Remove()傳遞實體,而不必關心它所屬的dbSet。

/// <param name="entity"></param>
public override void Update(Group entity) {
    // entity as it currently exists in the db
    var group = DbContext.Groups.Include(c => c.Contacts)
        .FirstOrDefault(g => g.Id == entity.Id);
    // update properties on the parent
    DbContext.Entry(group).CurrentValues.SetValues(entity);
    // remove or update child collection items
    var groupContacts = group.Contacts.ToList();
    foreach (var groupContact in groupContacts) {
        var contact = entity.Contacts.SingleOrDefault(i => i.ContactId == groupContact.ContactId);
        if (contact != null)
            DbContext.Entry(groupContact).CurrentValues.SetValues(contact);
        else
            DbContext.Remove(groupContact);
    }
    // add the new items
    foreach (var contact in entity.Contacts) {
        if (groupContacts.All(i => i.Id != contact.Id)) {
            group.Contacts.Add(contact);
        }
    }
    DbContext.SaveChanges();
}


Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow