2017-01-19 11 views
1

状況:私はタグのようなものがあります。ユーザーはいくつかのエンティティのタグのリストを変更できます。エンティティとタグには、多くの関係があります。Entity Frameworkの多対多リレーションを更新する

問題:新しいタグを追加したり、古いタグを削除したり、タグを変更せずに保存したりできます。例えば:前

  • :アフター
  • C、B、:タグ aが削除されたB、C、D

、タグdを添加しました。 SQLクエリの数を最小限に抑えてこれを行う最も効率的な方法は何ですか?

考えられる解決策

私は2つの解決策を見つけましたが、私はすべての古いタグを削除し、比較

  • // entityId - editing entity's id 
    // tagIds - new tags ids 
    
    var entity _entityRepository.GetAll() 
        .Include(x => x.Tags) 
        .FirstOrDefault(x => x.Id == entityId); 
    entity.Tags.RemoveAll(); 
    
    // Add new tags 
    entity.Tags = _tagsRepository.GetAll() 
        .Where(x => tagIds.Contains(x.Id)); //Yes, this .Contains works 
    
    _entityRepository.Update(entity); 
    
  • 新しいを追加し、彼らは

    1. 優れているとは思いません古いタグのリストを新しいタグのリストで置き換え、追加または削除して同等のものにします。

      // entityId - editing entity's id 
      // tagIds - new tags ids 
      
      var entity _entityRepository.GetAll() 
          .Include(x => x.Tags) 
          .FirstOrDefault(x => x.Id == entityId); 
      
      // Add tags which not exists in entity.Tag 
      foreach (var tagId in tagIds) 
      { 
          if (!entity.Tags.Any(x => x.Id == tagId)) 
          { 
           //A lot of queiries! 
           var newTag = _tagsRepository.GetAll() 
             .FirstOrDefault(x => x.Id == tagId); 
           entity.Tags.Add(newTag); 
          } 
      } 
      
      // Remove tags whic not exists in tagIds 
      // Assuming Tags is IList<T> and we can use [] 
      int i = 0; 
      
      while (i < entity.Tags.Count) 
      { 
          if (!tagIds.Contains(entity.Tags[i].Id)) 
           entity.Tags.RemoveAt(i); 
          else 
           i++; 
      } 
      
      _entityRepository.Update(entity); 
      

    ソリューションの長所と短所

    まずソリューションの長所:

    • 少数のSQLは、まずソリューション短所

    を照会します。

    • Include

    第二の溶液のプロを使用していないすべてのTagsをすべての関係を削除し、新しいを作成し、関係なく、彼らは

  • 負荷を変更しないんでした:

    • んが、すべての

    第二の溶液の短所を取り除きます:

    • すべての新しいタグに
    • ロードをロードするためのクエリの多くは、すべてのTags

    この問題に対する最善の解決策は何ですかIncludeを使用していますか?

  • 答えて

    2

    何も比較しないで、削除されたフラグと追加されたフラグを確認する 'ロジック'を実装しないでください。

    代わりに、エンティティにタグの新しいリストを割り当て、オブジェクトを保存するようにEntity Frameworkに指示します。それは、どれが削除されなければならないのか、どのものが追加されなければならないのか、それ自身で把握するでしょう。

    +0

    好奇心の高まりから、 'tagIds'リストだけを持っているとき、これがどのように機能しますか?エンティティに割り当てる*タグの*新しいリストをどのように取得しますか? Idプロパティが割り当てられた新しいタグオブジェクトでリストを作成すると、EFがタグレコードとリンクレコードの両方を挿入しようとしていることがわかります。 –

    +0

    私はいくつかのテストを行い、これを知っています:1.タグのコレクションを読み込んで新しいコレクションを割り当てます。 2 - 古いコレクションをロードせず、新しいコレクションを割り当てました。結果は両方のコレクションの関連付けになります。 –

    +0

    @AlexeyMarkov完全性を確認するために、この回答(例:オプション3)に基づいて投稿を更新するか(自己回答を投稿する)、1と2と同じ分析/比較を行うことができますか? –

    関連する問題