2

EF4 を使用して .NET 4.0 で LINQ to Entities クエリを実行する式ツリーを構築しようとしています。作成したクエリを実行しようとするNotSupportedExceptionと、次のメッセージが表示されます。

LINQ to Entities はメソッド 'System.Data.Objects.ObjectQuery`1[TestWpf.Customer] Where(System.String, System.Data.Objects.ObjectParameter[])' メソッドを認識せず、このメソッドを店舗表現。

Northwind データベースに対してクエリを実行しています。私のエンティティはデータベースから生成されました。以下のコードでは、メソッドGetQuery1()で構築しようとしているクエリがあり、メソッドで構築しようとしていGetQuery2()ます。

query1ブレークポイントを設定して変数を調べると、そのExpressionプロパティは次のようになります。

Convert(value(System.Data.Objects.ObjectSet`1[TestWpf.Customer])).MergeAs(AppendOnly).Where(c => c.CompanyName.Contains("z"))

これは何をしているのConvert().MergeAs(AppendOnly)ですか?MSDN で検索しようとしましたが、必要なものが見つかりませんでした (少なくとも、見つけられなかったと思います...)。さらに、私は何を間違っていますか?

Where()Intellisense が拡張メソッドである別のメソッドがあると言っているように、おそらく間違ったメソッドを呼び出していると思います。変数を更新してそのwhereMethod変数を取得しようとしたことはありませんが、その方法もわかりません。

private static IQueryable<Customer> GetQuery1(NorthEntities context) {
    return context.Customers.Where(c => c.CompanyName.Contains("z"));
}

private static IQueryable<Customer> GetQuery2(NorthEntities context) {
    var custParam = Expression.Parameter(typeof(Customer), "c");
    var custCollection = Expression.Constant(context.Customers);
    var companyNamePropValue = Expression.Property(custParam, typeof(Customer).GetProperty("CompanyName"));
    var containsParameter = Expression.Constant("z");
    var containsMethod = Expression.Call(companyNamePropValue, typeof(string).GetMethod("Contains"), containsParameter);
    var whereMethod = context.Customers.GetType().GetMethod("Where", new Type[] { typeof(string), typeof(ObjectParameter[]) });
    var param2 = Expression.Constant(new ObjectParameter[] { });
    var where = Expression.Call(custCollection, whereMethod, companyNamePropValue, param2);
    return ((IQueryable<Customer>)context.Customers).Provider.CreateQuery<Customer>(where);
}

private static void Main(string[] args) {
    using (var context = new NorthEntities()) {
        var query1 = GetQuery1(context);
        var query2 = GetQuery2(context);

        foreach (var c in query1)
            Console.WriteLine(c.CompanyName);
        foreach (var c in query2)
            Console.WriteLine(c.CompanyName);
    }

    Console.ReadLine();
}
4

1 に答える 1