0

Entity Frameworkコアを使用して簡単なwebapiを構築する。私はモデルとビューモデルを使ってクライアントが実際に受け取っているデータを管理しています。ここに私が作成したモデルとのviewmodelsです:Entity Frameworkコアで関連するデータを更新する

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

私は自分自身がチームに接続TeamAgentsを更新するためにどのような問題で捕まってしまいました。私が試して働いたことの一つは、すべてのTeamAgentを削除してから、チームのデータが更新されるたびに新しいTeamAgentを作成することでした。方法は次のとおりです:

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

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

これは明らかにそれを行うには良い方法ではありません。 Entity Frameworkコアで関連アイテムを更新する正しい方法は何ですか?

+0

/// <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(); } 
[保存データ - 切断エンティティ] EFコアの(https://docs.microsoft.com/en-us/ef/core/saving/disconnected-entities)セクション依然として空です。つまり、これを行うための良い(右の)一般的な方法はありません。 –

+0

@IvanStoev、あなたのコメントを回答として追加してください。私はそれを受け入れます。 – hs2d

+0

ありがとうございますが、これは間違いなく私が答えになりたいものではありません。うまくいけば、そのようなシナリオは、GraphDiff for EF6のようなMSやサードパーティのパッケージによって対処されることをうまく願っています。 –

答えて

0

Julie Lermanは、彼女の記事Handling the State of Disconnected Entities in EF(2016年4月から)でこれを解決しています。記事を読んでいない場合は、読む価値があります。残念ながら、EF Core 2.0の時点では、まだオブジェクトグラフを更新する方法はありません。

Julieの記事で述べたアプローチは、オブジェクトにプロパティを追加し、クライアントに状態を送信することによって、基本的に分離されたエンティティの状態を追跡することです。クライアントは状態を変更してサーバーに送り返すことができます。そして、その情報を使って正しいことを行うことができます。

私の最近のプロジェクトでは、主に子コレクションを更新する必要がある操作が1つしかないため、少し異なるアプローチをとっています。私はこれをやり直さなければならない時点で、おそらくジュリーの提案を心とリファクタリングに取り上げるでしょう。

基本的には手動オブジェクトグラフの更新です。これは、EF 6.0のアプローチとかなり似ています。注目すべきは、EFコアでは、エンティティを渡すRemove()を呼び出すだけで、それが属するdbSetを気にする必要はないということです。

関連する問題