web-dev-qa-db-ja.com

「LINQ式ノードタイプ「Invoke」は、LINQ to Entitiesではサポートされていません」-困った!

後のEFでは、Linqクエリの一部として使用される匿名関数を渡そうとしています。この関数はINTを渡してBOOLを返します(u.RelationTypeIdはINTです)。以下は私の機能の簡易版です。

public IEnumerable<UserBandRelation> GetBandRelationsByUser(Func<int, bool> relation)
{
    using (var ctx = new OpenGroovesEntities())
    {
        Expression<Func<UsersBand, bool>> predicate = (u) => relation(u.RelationTypeId);

        var relations = ctx.UsersBands.Where(predicate);

        // mapping, other stuff, back to business layer
        return relations.ToList();
    }
}

ただし、上記のエラーが表示されます。関数から述語を構築することで、すべてを正しく行っているようです。何か案は?ありがとう。

62
Ryan Peters

任意の.NET関数を渡そうとしている...エンティティフレームワークはどのようにそれをSQLに変換することを望みますか?代わりにExpression<Func<int, bool>>を使用するように変更して、そこからWhere句を作成できますが、特には簡単ではありませんが、書き換える必要があります。異なるパラメーター式を持つ式(つまり、元の式ツリーにあるパラメーター式をu.RelationTypeIdを呼び出す式に置き換えます)。

正直に言うと、メソッドに渡す式ツリーを作成するために使用するラムダ式でu.RelationTypeIdを指定するために、次のように使用する方が良いでしょう。

public IEnumerable<UserBandRelation> GetBandRelationsByUser(
    Expression<Func<UsersBand, bool>> predicate)
{
    using (var ctx = new OpenGroovesEntities())
    {
        var relations = ctx.UsersBands.Where(predicate);

        // mapping, other stuff, back to business layer
        return relations.ToList();
    }
}
47
Jon Skeet

私はこの非常にエラーを受け取っていたので、ダイナミックwhere句を構築するためにJoe Albahariによる PredicateBuilder でEntity Frameworkを使用しています。同じ状態になった場合は、AsExpandableメソッドを呼び出す必要があります。

Entity Frameworkでクエリする場合、最後の行を次のように変更します。

return objectContext.Products.AsExpandable().Where(predicate);

このメソッドはLINQKIT DLLの一部であり、これをつかむことができます here またはNuGetパッケージを介して here を使用できます。

すべてが正常に動作するようになりました。 :)

115

whereリクエストの前に述語Expand()メソッドを呼び出すことができます

3