首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用表达式树NotSupportedException动态构建NotSupportedException查询

使用表达式树NotSupportedException动态构建NotSupportedException查询
EN

Stack Overflow用户
提问于 2013-07-06 15:00:25
回答 1查看 396关注 0票数 2

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

LINQ到实体不识别方法'System.Data.Objects.ObjectQuery`1TestWpf.Customer Where(System.String,System.Data.Objects.ObjectParameter[])的方法,而且该方法不能转换为存储表达式。

我在查询北风数据库。我的实体是从数据库中生成的。在下面的代码中,我尝试在GetQuery1()方法中构建查询,并尝试在GetQuery2()方法中构建查询。

如果设置一个断点并检查query1变量,它的Expression属性是:

代码语言:javascript
复制
Convert(value(System.Data.Objects.ObjectSet`1[TestWpf.Customer])).MergeAs(AppendOnly).Where(c => c.CompanyName.Contains("z"))

这个Convert().MergeAs(AppendOnly)在做什么?我试图在MSDN上搜索,但找不到我需要的东西(至少我认为我找不到它.)。另外,我做错了什么?

我认为我可能调用了一个不正确的Where()方法,正如Intellisense说的那样,还有另一个方法,即扩展方法。我没有尝试更新whereMethod变量以获取该变量,但我也不确定如何进行更新。

代码语言:javascript
复制
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();
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-07-06 15:11:14

若要构造正在处理的特定查询,请尝试以下操作:

代码语言:javascript
复制
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扩展方法(例如,其中),您必须查看Queryable类:

代码语言:javascript
复制
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));
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17504119

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档