57
IQueryable<Organization> query = context.Organizations;

Func<Reservation, bool> predicate = r => !r.IsDeleted;

query.Select(o => new { 
    Reservations = o.Reservations.Where(predicate)
}).ToList();

このクエリは「Internal .NET Framework Data Provider error 1025」例外をスローしますが、以下のクエリはスローしません。

query.Select(o => new { 
    Reservations = o.Reservations.Where( r => !r.IsDeleted)
}).ToList();

最初のものを使用する必要があるのは、正しい述語を構築するためにいくつかの if ステートメントをチェックする必要があるためです。この状況では if ステートメントを使用できないことがわかっているため、デリゲートをパラメーターとして渡します。

最初のクエリを機能させるにはどうすればよいですか?

4

5 に答える 5

44

上記の答えは正しいですが、 select ステートメントの後にそれを使用しようとするときは、AsQueryable()明示的に呼び出さなければならないことに注意してFuncくださいExpression<Func>

これはおそらく元のポスターの問題でした。そうしないと、ほとんどの場合、コンパイラは を探しているのに を探していExpression<Func>ないと文句を言うからFuncです。

デモ: 以下は失敗します:

MyContext.MySet.Where(m => 
      m.SubCollection.Select(s => s.SubItem).Any(expr))
         .Load()

以下は機能しますが:

MyContext.MySet.Where(m => 
      m.SubCollection.Select(s => s.SubItem).AsQueryable().Any(expr))
         .Load()
于 2014-02-26T17:32:50.933 に答える
21

ping を送信してくれてありがとう。結局、私は正しい軌道に乗っていたと思います。

とにかく、繰り返しますが、LINQ to Entities (コメントで自分の思考プロセスに混乱したときに修正してくれた Jon Skeet に感謝します) はExpression Treesで動作します。プロジェクションがラムダ式を によって SQL に変換QueryProviderできるようにします。

通常は、 LINQ to Objects にFunc<>適しています。

したがって、この場合、Entity Framework を使用している場合、EF に渡されるすべての述語IQueryableExpression<Func<>>.

于 2012-12-13T18:59:26.547 に答える
5

別のシナリオでこの問題が発生しました。

ExpressionEF クエリに結合または渡すことができる述語でいっぱいの静的クラスがあります。それらの1つは次のとおりです。

    public static Expression<Func<ClientEvent, bool>> ClientHasAttendeeStatus(
        IEnumerable<EventEnums.AttendeeStatus> statuses)
    {
        return ce => ce.Event.AttendeeStatuses
            .Where(a => a.ClientId == ce.Client.Id)
            .Select(a => a.Status.Value)
            .Any(statuses.Contains);
    }

これは、Containsメソッド グループ呼び出しが原因で 1025 エラーをスローしていました。エンティティ フレームワークはExpressionを予期し、メソッド groupを検出したため、エラーが発生しました。ラムダ (式に暗黙的にキャストできる) を使用するようにコードを変換すると、エラーが修正されました

    public static Expression<Func<ClientEvent, bool>> ClientHasAttendeeStatus(
        IEnumerable<EventEnums.AttendeeStatus> statuses)
    {
        return ce => ce.Event.AttendeeStatuses
            .Where(a => a.ClientId == ce.Client.Id)
            .Select(a => a.Status.Value)
            .Any(x => statuses.Contains(x));
    }

余談ですが、式を次のように単純化しました。ce => ce.Event.AttendeeStatuses.Any(a => a.ClientId == ce.Client.Id && statuses.Contains(a.Status.Value));

于 2016-03-08T12:48:23.607 に答える