11

これが私の表現です:

Course course = db.Courses
  .Include(
    i => i.Modules.Where(m => m.IsDeleted == false)
      .Select(s => s.Chapters.Where(c => c.IsDeleted == false))
  ).Include(i => i.Lab).Single(x => x.Id == id);

原因が Modules 部分にあることはわかっていますがWhere(m => m.IsDeleted == false)、なぜエラーが発生するのでしょうか? さらに重要なことに、どうすれば修正できますか?

where句を削除すると正常に機能しますが、削除されたモジュールを除外したいと思います。

4

2 に答える 2

12

.Includeデータベースから関連するエンティティを熱心にロードするために使用されます。つまり、あなたの場合、モジュールとラボのデータがコースにロードされていることを確認してください。

内部のラムバ式は.Include、含める関連テーブルを Entity Framework に伝える必要があります。

あなたの場合、インクルード内で条件を実行しようとしているため、エラーが発生しています。

あなたのクエリは次のようです:

関連するモジュールとラボを使用して、指定された ID に一致するコースを検索します。一致するモジュールと章が削除されない限り。

それが正しければ、これはうまくいくはずです:

Course course = db.Courses.Include(c => c.Modules)
                          .Include(c => c.Lab)
                          .Single(c => c.Id == id && 
                                       !c.Module.IsDeleted &&
                                       !c.Chapter.IsDeleted);
于 2013-04-12T21:53:20.500 に答える
5

なぜエラーが発生するのですか?

IncludeEF チームがこの構文を導入した日を後悔することがあると想像できます。ラムダ式は、任意の有効な linq 式を使用して熱心な読み込みを微妙に操作できることを示唆しています。しかし、残念なことに、そうではありません。ここで説明したように、ラムダは、基になる「実際の」メソッドへの偽装された文字列引数としてのみ機能しますInclude

どうすれば修正できますか?

最良の方法は、別のクラス (DTO など) に投影することです。

db.Courses.Select(x => new CourseDto {
    Id = x.Id,
    Lab = x.Lab,
    Modules = x.Modules.Where(m => !m.IsDeleted).Select( m => new ModuleDto {
        Moudle = m,
        Chapters = x.Chapters.Where(c => c.IsDeleted)
    }
}).Single(x => x.Id == id);

しかし、それはあなたにとって大きな変更になるかもしれません。

もう 1 つのオプションは、遅延読み込みを無効にし、削除されていないコースのモジュールとチャプターを、Loadコマンドでコンテキスト内に事前に読み込むことです。リレーションシップの修正により、適切なナビゲーション プロパティが入力されます。IncludeforはLab正常に動作します。

ところで、この機能には変更要求があります。

于 2013-04-12T22:11:48.343 に答える