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();
}