gpt4 book ai didi

c# - 使用表达式树动态构建 EF4 查询,NotSupportedException

转载 作者:太空宇宙 更新时间:2023-11-03 11:01:36 25 4
gpt4 key购买 nike

我正在尝试构建表达式树以在 .NET 4.0 中使用 EF4 执行 LINQ to Entities 查询。当我尝试执行我构建的查询时,我收到一个包含以下消息的 NotSupportedException:

LINQ to Entities does not recognize the method 'System.Data.Objects.ObjectQuery`1[TestWpf.Customer] Where(System.String, System.Data.Objects.ObjectParameter[])' method, and this method cannot be translated into a store expression.

我正在查询 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();
}

最佳答案

要构建您正在使用的特定查询,请尝试以下操作:

private static IQueryable<Customer> GetQuery2(NorthEntities context) {
IQueryable<Customer> customers = context.Customers;
var custParam = Expression.Parameter(typeof(Customer), "c");
var companyNamePropValue = Expression.Property(custParam, typeof(Customer).GetProperty("CompanyName"));
var containsParameter = Expression.Constant("z");
var containsCall = Expression.Call(companyNamePropValue, typeof(string).GetMethod("Contains"), containsParameter);
var wherePredicate = Expression.Lambda<Func<Customer, bool>>(containsCall, custParam);
return customers.Where(wherePredicate);
}

一般来说,要访问 LINQ 扩展方法(例如 Where),您必须查看 Queryable 类:

var genericWhereMethod = typeof(Queryable).GetMethods()
.Single(m => m.Name == "Where"
// distinguishes between Where((T, int) => bool) and Where(T => bool)
&& m.GetParameters()[1].ParameterType
.GetGenericArguments()[0].GetGenericTypeDefinition() == typeof(Func<,>));

// make the Where method that applies to IQueryable<Customer>
var whereMethod = genericWhereMethod.MakeGenericMethod(typeof(Customer));

关于c# - 使用表达式树动态构建 EF4 查询,NotSupportedException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17504119/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com