强制转换LINQ表达式会抛出“.net框架内部数据提供程序错误1025”

本文关键字:数据 内部 程序 1025 错误 框架 net LINQ 转换 表达式 | 更新日期: 2023-09-27 18:13:15

以下代码:

model.Items = dbQuery.Select(c => new Item {
    Total = c.Items.Count((Func<Item, bool>)(t => t.Amount.HasValue))
}).ToArray();

抛出以下异常:

内部。net框架数据提供程序错误1025.

但是减去强制转换后的确切代码是有效的:

model.Items = dbQuery.Select(c => new Item {
    Total = c.Items.Count(t => t.Amount.HasValue)
}).ToArray();

注:dbQuery只是一个EF ObjectQuery

Count()的预期类型是Func<Item, bool>, ReSharper甚至验证了它们是相同的类型,因为它使cast变灰,这表明它不需要,它们在功能上是等效的。

然而,异常证明它们不是,事实上,它们在功能上是等价的。

另外,我确实看到了这个相关的问题/答案,但是Count()(在这种情况下,无论如何)不会接受Expression<Func<Item bool>>,所以这对我不起作用。

强制转换LINQ表达式会抛出“.net框架内部数据提供程序错误1025”

您想要"将[表达式]存储在一个变量中,以便重用,并将其传递给Count()"。如果Expression可以转换为SQL,这是100%可能的。这里的问题是,您引入了一些不能转换为SQL的东西。这种情况下的特殊问题是转换被转换为Expression.Convert。您的类型肯定不是用SQL表示的,所以这将无法执行。将两者都插入LINQPad并检查IL以查看差异。

作为您链接到建议的其他相关问题/答案,您需要将谓词传递为Expression而不是Func (如何完成工作与指向代码中的位置)。正如您所指出的,问题是Count方法不采用Expression,但这很容易通过使用AsQueryable()来解决,这将为您提供采用ExpressionIQueryable扩展方法。

执行应该没有问题:

Expression<Func<Item,bool>> predicate = i => i.Amount.HasValue;
model.Items = dbQuery.Select(c => new Item {
    Total = c.Items.AsQueryable().Count(predicate)
}).ToArray();

问题是数据提供程序无法将该LINQ表达式转换为SQL语句。在不工作的情况下,Count被传递给一个方法的委托。可以把它看作是传递一个指针给如下方法:

private static bool MyFunction(Item item)
{
    return item.Amount.HasValue; 
}

现在,问题是数据提供者不打算进入那个方法,并试图找出如何把它变成SQL。

数据提供程序非常有能力遍历表达式树来构建SQL,这就是"减类型转换"示例的工作方式,也是您帖子中链接的相关答案。

如果你能更新你的帖子,你正在努力完成的,我也许能帮助你。