转换LINQ表达式会引发“内部.NET Framework数据提供程序错误1025”。

时间:2014-07-15 18:12:13

标签: c# linq entity-framework

以下代码:

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

引发以下异常:

  

内部.NET Framework数据提供程序错误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证实,它们是相同的类型,因为它会抛弃掉,表明它不需要它们'在功能上等同。

然而,异常证明它们,实际上在功能上是等效的。

此外,我确实看到this related question/answer,但Count()(在这种情况下,无论如何)都不会接受Expression<Func<Item bool>>,因此对我不起作用。

2 个答案:

答案 0 :(得分:11)

您希望将[]表达式存储在变量中,以便重复使用,并将其传递给Count()&#34;。如果Expression可以转换为SQL,则这是100%可能的。这里的问题是您正在引入无法转换为SQL的内容。在这种情况下的特殊问题是演员表被转换为Expression.Convert。您的类型肯定不会在SQL中表示,因此无法执行。将两者插入LINQPad并检查IL以查看差异。

正如您链接到的其他相关问题/答案建议的那样,您需要将谓词作为Expression而不是Func如何)传递给作品vs指向执行工作的代码中的位置。正如您所指出的那样,问题是Count方法不会使用Expression,但使用AsQueryable()可以很容易地解决这个问题,这会为您提供IQueryable Expression

的扩展方法

执行时应该没有问题:

Expression<Func<Item,bool>> predicate = i => i.Amount.HasValue;

model.Items = dbQuery.Select(c => new Item {
    Total = c.Items.AsQueryable().Count(predicate)
}).ToArray();

答案 1 :(得分:1)

问题是数据提供程序无法将该LINQ表达式转换为SQL语句。在没有工作的那个中,Count被传递给一个方法的委托。可以把它想象为将指针传递给类似的方法:

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

现在,问题在于数据提供者不会试图弄清楚如何将其转换为SQL。

数据提供程序非常能够遍历表达式树来构建SQL,这就是“减去投射”示例的工作方式,以及您帖子中链接的相关答案。

如果您可以根据自己的目标更新帖子,我可能会帮助您。