EntitySet.Where(myPredicate) 抛出 NotSupportedException

2023-12-01

EDIT: 我们再试一次。这次我使用了 AdventureWorks 示例数据库,以便大家可以一起玩。这将排除我在自己的数据库中所做的任何疯狂的事情。这是一个新示例,展示了哪些有效以及我期望哪些有效(但无效)。任何人都可以解释为什么它不起作用或建议一种不同的方式来实现我的目标(重构通用表达式,以便它可以在其他地方重用)?

using (AdventureWorksDataContext db = new AdventureWorksDataContext())
{
    // For simplicity's sake we'll just grab the first result.
    // The result should have the name of the SubCategory and an array of Products with ListPrice greater than zero.
    var result = db.ProductSubcategories.Select(subCategory => new
    {
        Name = subCategory.Name,
        ProductArray = subCategory.Products.Where(product => product.ListPrice > 0).ToArray()
    }).First();
    Console.WriteLine("There are {0} products in SubCategory {1} with ListPrice > 0.", result.ProductArray.Length, result.Name);
    // Output should say: There are 3 products in SubCategory Bib-Shorts with ListPrice > 0.

    // This won't work.  I want to pull the expression out so that I can reuse it in several other places.
    Expression<Func<Product, bool>> expression = product => product.ListPrice > 0;
    result = db.ProductSubcategories.Select(subCategory => new
    {
        Name = subCategory.Name,
        ProductArray = subCategory.Products.Where(expression).ToArray() // This won't compile because Products is an EntitySet<Product> and that doesn't have an overload of Where that accepts an Expression.
    }).First();
    Console.WriteLine("There are {0} products in SubCategory {1} with ListPrice > 0.", result.ProductArray.Length, result.Name);
}

</Edit>

以下 LINQ to SQL 工作正常:

var result = from subAccount in db.SubAccounts
             select new ServiceTicket
             {
                 MaintenancePlans = subAccount.Maintenances.Where(plan => plan.CancelDate == null && plan.UpgradeDate == null).Select(plan => plan.ToString()).ToArray()
                 // Set other properties...
             };

但是,我想分解传递给的谓词Where因为它在整个代码中都被使用。但是如果我尝试将定义的谓词传递给Where它失败了,例如:

Func<DatabaseAccess.Maintenance, bool> activePlanPredicate = plan => plan.CancelDate == null && plan.UpgradeDate == null;
var result = from subAccount in db.SubAccounts
             select new ServiceTicket
             {
                 MaintenancePlans = subAccount.Maintenances.Where(activePlanPredicate).Select(plan => plan.ToString()).ToArray()
                 // Set other properties...
             };

这对我来说毫无意义。谁能解释一下发生了什么事吗?Maintenances属于类型EntitySet<DatabaseAccess.Maintenance>。我得到的错误是:

系统不支持异常: 用于查询的重载不受支持 运算符“哪里”..

EDIT:对于那些感兴趣的人,以下是 Reflector 对于第一个(工作)示例的优化设置为 .NET 2.0 的内容:

using (BugsDatabaseDataContext db = new BugsDatabaseDataContext())
{
    ParameterExpression CS$0$0001;
    ParameterExpression CS$0$0006;
    ParameterExpression CS$0$0010;
    return db.SubAccounts.Select<SubAccount, ServiceTicket>(Expression.Lambda<Func<SubAccount, ServiceTicket>>(
        Expression.MemberInit(
            Expression.New(
                (ConstructorInfo) methodof(ServiceTicket..ctor), 
                new Expression[0]), 
                new MemberBinding[] 
                { 
                    Expression.Bind(
                        (MethodInfo) methodof(ServiceTicket.set_MaintenancePlans), 
                        Expression.Call(
                            null, 
                            (MethodInfo) methodof(Enumerable.ToArray), 
                            new Expression[] 
                            { 
                                Expression.Call(
                                    null, 
                                    (MethodInfo) methodof(Enumerable.Select), 
                                    new Expression[] 
                                    { 
                                        Expression.Call(
                                            null, 
                                            (MethodInfo) methodof(Enumerable.Where), 
                                            new Expression[] 
                                            { 
                                                Expression.Property(CS$0$0001 = Expression.Parameter(typeof(SubAccount), "subAccount"), (MethodInfo) methodof(SubAccount.get_Maintenances)), 
                                                Expression.Lambda<Func<Maintenance, bool>>(
                                                    Expression.AndAlso(
                                                        Expression.Equal(
                                                            Expression.Property(CS$0$0006 = Expression.Parameter(typeof(Maintenance), "plan"), (MethodInfo) methodof(Maintenance.get_CancelDate)), 
                                                            Expression.Convert(Expression.Constant(null, typeof(DateTime?)), typeof(DateTime?)), false, (MethodInfo) methodof(DateTime.op_Equality)
                                                        ), 
                                                        Expression.Equal(
                                                            Expression.Property(CS$0$0006, (MethodInfo) methodof(Maintenance.get_UpgradeDate)), 
                                                            Expression.Convert(Expression.Constant(null, typeof(DateTime?)), typeof(DateTime?)), false, (MethodInfo) methodof(DateTime.op_Equality)
                                                        )
                                                    ), 
                                                    new ParameterExpression[] { CS$0$0006 }
                                                ) 
                                            }
                                        ), 
                                        Expression.Lambda<Func<Maintenance, string>>(
                                            Expression.Call(
                                                CS$0$0010 = Expression.Parameter(typeof(Maintenance), "plan"), 
                                                (MethodInfo) methodof(object.ToString), 
                                                new Expression[0]
                                            ), 
                                            new ParameterExpression[] { CS$0$0010 }
                                        ) 
                                    }
                                ) 
                            }
                        )
                    )
                }
            ), 
            new ParameterExpression[] { CS$0$0001 }
        )
    ).ToList<ServiceTicket>();
}

EDIT:第二个示例(使用谓词)的 Reflector 输出大部分相似。最大的区别在于,在调用Enumerable.Where,而不是通过Expression.Lambda它过去了Expression.Constant(activePlanPredicate).


我不完全理解 Linq to Entities 的本质,但是有一个专门为帮助解决这个问题而设计的开源(可在专有软件中使用)工具包,称为 LinqKit,链接到这篇与 O'Reilly 相关的文章:

http://www.albahari.com/nutshell/predicatebuilder.aspx

由于我不太明白其中的内容,我就简单引用一下:

实体框架的查询处理管道无法处理调用表达式,这就是您需要对查询中的第一个对象调用 AsExpandable 的原因。通过调用 AsExpandable,您可以激活 LINQKit 的表达式访问者类,该类用实体框架可以理解的更简单的构造替换调用表达式。

Here is 直接链接到 LinqKit.

以下是该项目支持的代码类型:

using LinqKit;

// ...

Expression<Func<Product, bool>> expression = product => product.ListPrice > 0;

var result = db.ProductSubcategories
    .AsExpandable() // This is the magic that makes it all work
    .Select(
        subCategory => new
        {
            Name = subCategory.Name,
            ProductArray = subCategory.Products
                // Products isn't IQueryable, so we must call expression.Compile
                .Where(expression.Compile())
        })
    .First();

Console.WriteLine("There are {0} products in SubCategory {1} with ListPrice > 0."
    , result.ProductArray.Count()
    , result.Name
    );

结果是:

子类别背带裤中有 3 件产品,其列表价格 > 0。

是的,也不例外,我们可以提取谓词!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

EntitySet.Where(myPredicate) 抛出 NotSupportedException 的相关文章

随机推荐

  • 任务“:app:checkDebugAarMetadata”执行失败

    我在运行我的应用程序时收到此错误 Execution failed for task app checkDebugAarMetadata gt Could not resolve all files for configuration ap
  • 增量定义?

    无论如何 每次使用它时都有一个定义的增量吗 例如 int a ADEFINE int b ADEFINE a 为 1 b 为 2 您可以使用 COUNTER 尽管这不是标准的 MSVC 和 GCC 都支持它 如果你可以使用boost 预处理
  • p:fileUpload 在哪里保存我的文件?

    我的页面上有一个 p fileUpload 函数 每次上传文件时 我似乎都无法在 web xml 文件中指定的文件夹中找到它 我已将以下 jar 添加到我的库中 primefaces 3 2 jar commons io 2 3 jar c
  • SVG tspan 未与 text-anchor="end" 对齐的问题

    我有一些这样的代码 svg font family Verdana sans serif color 000 key font size 75 overflow visible caphgh font weight bold keynor
  • 这段代码的作用是什么?

    我不太确定这意味着什么或它在做什么 有人可以详细说明吗 Player player Player sender 它获取发送者引用的对象 并尝试将其转换为 Player 类型 Java 对象是强类型的 这意味着您必须声明对象的类型 如果发送者
  • 如何在 TFS 中反序列化和序列化构建过程参数

    我正在尝试使用 TFS 2013 API 创建新的构建定义 我必须引用的流程模板包含几个自定义活动和参数 创建构建定义时 一些属性值需要动态更新 所以我尝试使用以下代码反序列化过程参数 IDictionary
  • 多个自定义滚动条

    我想知道的是是否可以在同一页面上有多个定制的 webkit scrollbars 我制作了一些特定的 div 颜色 例如一个 div 有绿色文本和图像 另一个有蓝色等 所以我想为每个 div 制作一个自定义滚动条 使其与颜色匹配 Q1 可以
  • 如何使用 Google 脚本将日历事件复制(复制)到另一个日历中?

    我在 Google 日历中有几个日历 我正在学习 Google 脚本 并希望创建一个脚本 将事件从我的一个日历复制到另一个日历 并有机会修改参数 例如重复发生 一些代码开始 function myFunction var calendarS
  • 检查列表列表中是否存在某个项目的最佳方法? [复制]

    这个问题在这里已经有答案了 我有这样的示例列表 example list aaa fff gg ff gg 现在 我检查它是否有空字符串 如下所示 has empty False for list1 in example list for
  • bash: /bin/myscript: 权限被拒绝

    我已将文件夹的路径添加到 linux mint 15 中的 bashrc 其中包含我的脚本 据我所知 我的脚本应该像 bash 脚本一样工作 但每次我尝试使用我的脚本之一时 都会出现以下错误 bash bin myscript permis
  • iPhone Facebook Graph API 库

    是否存在使用新 Facebook Graph API 的 iPhone 库 这个库很棒 http www capturetheconversation com technology iphone facebook oauth 2 0 and
  • 处理响应 - SyntaxError:使用模式时出现意外的输入结束:“no-cors”

    我尝试了对 REST API 的 ReactJS 获取调用 并希望处理响应 调用成功 我收到响应 我可以在 Chrome 开发工具中看到该响应 function getAllCourses fetch http localhost 8080
  • MySQL 非主键自增

    我想知道是否 如何可以为每个主键设置第二列自动增量 CREATE TABLE test id INTEGER UNSIGNED NOT NULL subId INTEGER UNSIGNED NOT NULL AUTO INCREMENT
  • 扩展方法和动态对象

    我将把我的问题总结为以下代码片段 List
  • 仅限于 N 元解的背包算法

    这段摘自 CRAN 文档的 adagio 函数 knapsack 的功能符合预期 它用利润向量解决了背包问题p 权重向量w 和容量cap 在所选元素的总权重不超过容量的约束下 选择利润最大的元素子集 library adagio p lt
  • WooCommerce - 在购物车页面上取消设置“<产品> 删除通知...”

    动作和过滤器 在我的 WooCommerce 网站上 当我从购物车中删除产品时 我收到以下消息
  • 快速替换 NA - 错误或警告

    我有一个名为 mat 的大 data frame 包含 49952 个 obs 7597 个变量 我正在尝试用零替换 NA 这是我的 data frame 的示例 A B C E F D Q Z 1 1 1 0 NA NA 0 NA NA
  • SonarQube:自创建以来未进行任何分析。唯一可用的部分是配置

    我是 SonarQube 新手 我通过 sonar eclipse plugin 在 eclipse 中运行分析 但在远程服务器上 它显示 自创建以来未进行任何分析 唯一可用的 部分是配置 如何在服务器上看到分析结果 这意味着您有配置您的项
  • sendto:资源暂时不可用(errno 11)

    我在使用 sendto 时遇到问题 我有一个接收者 它使用recvfrom接收UPD数据包 然后使用sendto回复发送者 不幸的是 我收到 errno 11 资源暂时不可用 我正在使用两个套接字 第一个数据包实际上已发送 但后面的数据包并
  • EntitySet.Where(myPredicate) 抛出 NotSupportedException

    EDIT 我们再试一次 这次我使用了 AdventureWorks 示例数据库 以便大家可以一起玩 这将排除我在自己的数据库中所做的任何疯狂的事情 这是一个新示例 展示了哪些有效以及我期望哪些有效 但无效 任何人都可以解释为什么它不起作用或