0

私は2つのオブジェクト間に多対多の関係を持っています:

[Table("AEntities")]
public abstract class AEntity { 
 public int AEntityID { get; set; } 
 public string Description { get; set; }
 public virtual ICollection<Tag> Tags { get; set; }
}

そしてタグ:

public class Tag {
 public int TagID { get; set; }
 public int AEntityID { get; set; }
 public string TagValue { get; set; }
}

マッピングテーブル:

public class AEntityTags {
    public int AEntityTagID { get; set; }
    public int TagID { get; set; }
    public int AEntityID { get; set; }
}

マッピングを定義するための流暢なコード:

        modelBuilder.Entity<AEntity>() 
            .HasMany(t => t.Tags)
            .WithMany(p=>p.AEntity) 
            .Map(t => t.MapLeftKey("AEntityID") 
                .MapRightKey("TagID") 
                .ToTable("AEntityTags"));

次に、特定のセットの個別のタグのリストを取得しようとしていますAEntities。したがってAEntity、最後に3つのオブジェクトがある場合、これら3つのエンティティのいずれかにあるすべてのタグのリストが必要です。

私は現在、次のクエリでこれを達成できます。

    public IEnumerable<Tag> getTagsOnAEntities(IEnumerable<AEntities> aEntities) {
        IEnumerable<Tag> results = _context.Tags
            .AsEnumerable()
            .Where(p => p.AEntities.Any(o=>aEntities.Contains(o)));
        return results;
    }

これらが使用される場合、プロジェクトで使用された回数を取得するために追加のルックアップを強制します(つまり、使用されたときt.TagValueとを印刷していt.AEntities.Count()ます)。

しかし、予想されるように、AEntity(数千)とTags(数万のマッピング)の数が増えるにつれて、信じられないほど遅くなります(〜10秒)。非効率性がどこで発生しているのか(数千のDB呼び出し)を理解しており、最善のアプローチを決定するのに苦労しているため、アプローチに関するアドバイスを探しています。私は次の問題を抱えています:

  1. DBでタグが使用された回数を全体的に数えた後、AEntityTagsテーブルにカウントを個別にクエリしようとしましたTagID(何かの読み込みをスキップするので高速ですが、それでも低速です)-EF内にとどまるよりも良い方法があります?

  2. Tagのサブセットでaが使用された回数を決定する効率的な方法はありAEntitiesますか?

4

1 に答える 1

1

あなたのデータベースに似たものをテストするのに便利なものはありませんが、クエリのパフォーマンスのためにこれを試してみることをお勧めします。

IEnumerable<Tag> results = aEntities.SelectMany(e=>e.Tags).Distinct(); 
于 2013-02-21T22:27:19.717 に答える