2

Entity Frameworkは、多対多の関係テーブルに接続された2つのデータベーステーブル(たとえば、Table1とTable2)のObjectContextを生成する場合、外部参照テーブルのオブジェクトを作成せず、代わりに、関係。したがって、Table1にはがEntityCollection<Table2> Table2sあり、Table2にはがありますEntityCollection<Table2> Table1s。ほとんどの場合、それは実際にはかなり素晴らしいです...

ただし、このシナリオでは、Table1.Table2sコレクションに含まれるべきTable2行のデータベースIDを表す整数のリストがあります。

エンティティキーを使用してそのコレクションを設定する方法がわからないため、これらをObjectContextに選択することに固執しています。これは、理由もなく、すでに大量の作業を行っています。LINQ-to-Entitiesがインテリジェントに実行を延期し、SQLサーバー上ですべてを実行することを期待しています(ただし、WhereはContainsを使用しますが、SQLではIN()に正しく変換される場合とされない場合があります)。だから私はまで行くことができます:

table1instance.Table2s.Clear();
var table2sToInclude = context.Table2s.Where(
  t => 
  listOfTable2DatabaseIds.Contains(t.Id));

しかし、もちろん拡張方法EntityCollection<T>.AddRange(IEnumerable<T>)もありIEnumerable<T>.ToEntityCollection<T>()ませんので、現時点ではこれらの結果をどうするかわかりません。私にできることは

foreach (var table2 in table2sToInclude)
{
  table1instance.Table2s.Add(table2);
}

これはばかげているようで、多くの不必要な評価を強いられることを私は知っています。

これを行うための「正しい」、またはおそらく「ラメの少ない」方法はありますか?

4

1 に答える 1

2

いいえ EF は、クエリの実行を延期しません。選択からの挿入のようなものはありません。Linq-to-entities は単なるクエリ言語であり、クエリの責任は実行することです。これは、EF 自体が提供する永続化機能とは厳密に分離されています。

table1 の既存のアイテムと table2 の既存のアイテムの間にリレーションを作成する場合は、次のようなコードを使用できます。

using (var ctx = new YourContext())
{
    var table1 = new Table1 { Id = 123 };
    ctx.Table1s.Attach(table1);

    foreach (var table2 in table2sToInclude.Select(id => new Table2 { Id = id }))
    {
        ctx.Table2s.Attach(table2);
        order.Table2s.Add(table2);
    }
    ctx.SaveChanges();
}

このコードは、データベースから単一のレコードをロードすることなく、ID 123 の Table1 の項目と table2sToInclude からのすべての Table2 の項目との間の関係を作成します。

レコードを 1 つずつ追加するのが「不自由」な理由は何ですか? の利点はAddRange何ですか?AddRange典型的なコレクションでは、内部配列の容量を拡張し、アイテムを拡張配列にコピーするだけです。EntityCollectionは一般的な配列ではなく、追加された各エンティティを処理する必要があります。そのため、いくつかある場合でも、AddRangeアイテムを内部的に反復し、それらを 1 つずつ処理します。

于 2011-05-30T20:27:47.363 に答える