0

Im使用Entity Framework Core構建簡單的webapi。我使用模型和視圖模型來管理客戶端實際接收的數據。這裏的模型和的ViewModels我創建:使用Entity Framework Core更新相關數據

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; } 
} 

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

[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); 
} 

我給自己買了卡在這個問題如何更新連接到球隊TeamAgents 。我嘗試過的所有工作之一就是刪除所有的TeamAgents,然後在每次更新Team數據時創建新的TeamAgents。這是如何:

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

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

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

+0

[保存數據 - 斷開實體]的EF核心的(https://docs.microsoft.com/en-us/ef/core/saving/disconnected-entities)部分仍然是空的。這意味着沒有好的(正確的)通用方法來做到這一點。 –

+0

@IvanStoev,請添加您的評論作爲答案,我會接受它。 – hs2d

+0

謝謝,但這絕對不是我想成爲答案的東西。希望在某些時候,這樣的場景可以通過MS或第三方軟件包如GraphDiff for EF6解決。 –

回答

0

Julie Lerman在2016年4月的文章Handling the State of Disconnected Entities in 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(); 
} 
相關問題