2

dbcontext apiは、ナビゲーションプロパティをICollectionsに設定しているようです(関連付けの*終了用)。クエリ可能なオブジェクトを取得する通常の方法(カウントが必要な場合など)は、

int count = dbcontext.Entry(entry).Collection(c => c.navprop).Query().Count();

ただし、データベースを頻繁にフィルタリングする場合は不便です。さらに重要なことは、それも忘れがちです。誰かが誤って言った場合

int count = entry.navprop.Count();

次に、サーバー上のすべてのデータを取得し、そこでカウントを実行しますが、これは低速です。

ObjectContextがデフォルトで使用するEntityCollectionタイプについても同じことが言えます。

int count = entry.navprop.CreateSourceQuery().Count();

ナビゲーションプロパティのデフォルトのコレクションタイプがIQueryableまたはObjectQuery、あるいはある種のクエリ可能なタイプであることをモデルまたは他の場所に設定する方法はありますか?

コンテキスト内の実際のオブジェクトセットとdbsetアイテムはクエリ可能であるように見えるため、これはナビゲーションプロパティの問題にすぎないことに注意してください。

4

2 に答える 2

1

私は自分の問題のほとんどを解決する解決策を思いついた。最終的に私が行ったのは、ObjectContext APIとモデルを使用し、(取得と設定のために)プライベートにアクセスするのに長い時間がかかっていたナビゲーションプロパティを作成することでした。navプロパティを右クリックすると、edmxファイルでこれを行うことができます。

次に、プライベートナビゲーションプロパティを含むクラスの部分クラスファイルを作成し、これに沿って何かを追加しました。

public ObjectQuery<NavPropType> NavPropName
{
   get
   {
      if(privateNavProp != null) //in case lazy loading is disabled or something
         return privateNavProp.CreateSourceQuery();
      else
         return null;
   }
}

これで、クラスのユーザーが誤ってすべてのnavpropアイテムを取り込もうとすることはありません。また、毎回CreateSourceQueryを呼び出すことを忘れずに、navプロップでクエリを作成するのも簡単です。

そのナビゲーションプロパティはアプリケーションで読み取り専用であるため、セッターを追加しませんでした。このパターンに適合するものを作成する方法があると確信していますが、ObjectContext APIについては、その方法を説明するのに十分な知識がありません。

他のプロパティをそのままにしておくとパフォーマンスに影響がなかったため、大量のデータが背後にある可能性のあるナビゲーションプロパティに対してのみこれを行うことになりました。

編集:私が後で遭遇したことをプライベートにすることの1つの欠点は、私がもはやすることができなかったことです

db.EntryTable.OrderBy(e => e.privateNavProp.Count())

すべてのエンティティを取得できないほど賢いのに

于 2013-03-28T18:19:34.593 に答える
0

いいえ。IQueryableはコレクションではありません。IQueryableは、実装がデータソースに対してクエリを評価するインターフェイスです(コレクションがデータソースになります)。

エンティティオブジェクトをロードするときにカウントをロードすることもできますが、無害なメソッド呼び出しをインライン化することが目的でない場合は、次のようにします。

from e in EntityA
<optional where clause for entity>
select new
{
    Entity = e,
    filteredNavPropCount = e.navprop.Where( np => <optional where clause for collection> ).Count()
}
于 2013-03-27T03:55:08.870 に答える