0

データベース内の3つのテーブルを1つのPUTメソッドから更新しようとしています。私のWebページではJSONを作成し、Web APIにPUTメソッドで送信します。 PUTメソッドは、vs2017によって生成されたデフォルトの方法です:私は3機種持っ"PUT"メソッドからの更新をカスケードして、mysqlの多対多リレーションシップのすべてのテーブルを更新する方法はありますか?

// PUT: api/Engineers/5 
[HttpPut("{id}")] 
public async Task<IActionResult> PutEngineer([FromRoute] int id, [FromBody] Engineer engineer) 
{ 
    if (!ModelState.IsValid) 
    { 
     return BadRequest(ModelState); 
    } 

    if (id != engineer.EngineerId) 
    { 
     return BadRequest(); 
    } 

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

    try 
    { 
     await _context.SaveChangesAsync(); 
    } 
    catch (DbUpdateConcurrencyException) 
    { 
     if (!EngineerExists(id)) 
     { 
      return NotFound(); 
     } 
     else 
     { 
      throw; 
     } 
    } 

    return NoContent(); 
} 

:Engineer.cs、Application.csを、テーブルEngineerApplications.csに参加。これらのテーブルは、エンジニアがサポートしているアプリが多く、アプリにサポートしているエンジニアが多い多対多の関係になっています。

Engineer.cs:

public class Engineer 
{ 
    ...Some Stuff Here... 

    //Navigation Property 
    public ICollection<EngineerApplications> EngineerApplications { get; set; } 
} 

Application.cs:

public class Application 
{ 
    ...Some Stuff Here... 

    //Navigation Property 
    public ICollection<EngineerApplications> EngineerApplications { get; set; } 
} 

EngineerApplications.cs:

public class EngineerApplications 
{ 
    public int EngineerId { get; set; } 
    public int ApplicationId { get; set; } 
    public Engineer Engineer { get; set; } 
    public Application Application { get; set; } 
} 

JSON:

[{ 
    "engineerId": 1, 
    "supportedApplications": [{ 
     "application": { 
      "applicationId": 1, 
      "engineerApplications": null 
     }, 
     "applicationId": 1, 
     "engineer": { 
      "engineerId": 1, 
      "engineerApplications": null 
     }, 
     "engineerId": 1 
    }, 
    { 
     "application": { 
      "applicationId": 2, 
      "engineerApplications": null 
     }, 
     "applicationId": 2, 
     "engineer": { 
      "engineerId": 1, 
      "engineerApplications": null 
     }, 
     "engineerId": 1 
    }] 
}, 
... 
] 

このJSONが後ろのPUTメソッドに当たると、エンジニアテーブルを更新したいのですが、EngineerApplicationsとApplicationsテーブルも更新したいと思います。現在、エンジニアテーブルのみが更新されます。

私はC#/ Web API/EFcore/etcの初心者で、これをどうやって行うのか分かりません。私は解決策を見回しましたが、うまく機能しているか、それとも私のコードに似たものが見つかりませんでした。

他の2つのテーブルを手動で更新する必要があると仮定しますが、それを行う方法もわかりません。

+2

、エンティティを取得し、あなたのビューモデルに応じて、すべての変更を適用し、あなたのDbContextインスタンスにSaveChangesMethodを呼び出し、それが理にかなっていますか? –

+0

非常に高いレベルでは論理が理にかなっています。残念ながら、私はそれらのことを行う方法を理解していません。 idkどのようにエンティティを取得するか、idkどのように変更を適用するか。 – Paulo

答えて

0

あなたのコードによれば、私はいくつかのことを前提に1つの解決策を提供します。

あなたの質問を解決するために、これらの手順を実行する必要があります。

  1. はチャイルズ
  2. チャイルズ
  3. 保存
  4. を変更するためのエンティティ
  5. 設定の変更のための設定の変更を使用してエンティティを取得

サンプルコード:

// PUT: api/Engineers/5 
[HttpPut("{id}")] 
public async Task<IActionResult> PutEngineer([FromRoute] int id, [FromBody] Engineer engineer) 
{ 
    if (!ModelState.IsValid) 
    { 
     return BadRequest(ModelState); 
    } 

    // Retrieve engineer by id 
    var entity = await _dbContext.Engineers 
     .Include(p => p.EngineerApplications) 
     .FirstOrDefault(item => item.EngineerId == id); 

    if (entity == null) 
    { 
     return NotFound(); 
    } 

    // Set changes (exclude entity's key) 
    entity.FirstName = engineer.FirstName; 
    entity.MiddleName = engineer.MiddleName; 
    entity.LastName = engineer.LastName; 

    // There another ways to check engineer applications, 
    //in this case we want to update not add 
    // So we don't worry about to check if child if exists or not 
    if (engineer.EngineerApplications.Count == entity.EngineerApplications.Count) 
    { 
     // Apply changes in navigation properties 
     for (var i = 0; i < entity.EngineerApplications.Count; i++) 
     { 
      // Set changes, assuming those values are in engineer instance 
      entity.EngineerApplications[i].Active = engineer.EngineerApplications[i].Active; 
     } 
    } 

    try 
    { 
     await _context.SaveChangesAsync(); 
    } 
    catch (DbUpdateConcurrencyException ex) 
    { 
     // Add logging for exception 
     return new ObjectResult(entity) { StatusCode = (int)HttpStatusCode.InternalServerError }; 
    } 

    return Ok(entity); 
} 

このコードを使用すると、エンティティの更新を実行します。あなたのputメソッドで

よろしく

関連する問題