使用自定义函数过滤IQueryable会导致运行时错误

本文关键字:运行时错误 IQueryable 自定义函数 过滤 | 更新日期: 2023-09-27 18:10:59

我有一个类似的查询LINQ:如何从IQueryable在很大程度上,它回答了我的问题。

我的代码设置类似:

var items = MyDataContext.Items.Where(x =>MyFunction(x.value1, x.value2, x.value3));
...
...
bool MyFunction(decimal val1, decimal val2, decimal val3)
{
 //some calculation with the parameters
 return true;
}

它编译得很好,但是当我运行它时,它抛出了一个错误:

"类型为'System '的异常。日志含义发生NotSupportedExceptionSystem.Data.Entity.dll,但在用户代码

中未处理

附加信息:LINQ to Entities不识别该方法"布尔MyFunction(系统。小数,系统。小数,System.Decimal) '方法,并且无法将此方法转换为存储表达式。"

我是linq的新手,这周才开始,所以任何帮助都很感激。谢谢!

使用自定义函数过滤IQueryable会导致运行时错误

您的linq查询被翻译成SQL。在这种情况下,Linq to Entities不知道如何正确地将您的方法转换为SQL。因此,您不能在linq to sql查询中使用自定义方法。你只能使用支持的方法

如果你想这样做,你必须从数据库中获取所有数据并在内存中完成。

如果您想完美地运行这段代码,您应该像这样使用ienumerable:

var items = MyDataContext.Items.toList().Where(x =>MyFunction(x.value1, x.value2, x.value3));

尝试在where子句之前添加.ToList()

我猜你正在查询某种类型的数据库,但数据提供程序无法翻译你的方法Myfunction

在触发where子句之前将数据放入内存:

var items = MyDataContext.Items.ToList().Where(x =>MyFunction(x.value1, x.value2, x.value3)

从我的瞬间来看,有一些额外的解释需要。查询直到真正需要时才执行。通过调用.ToList(),您实现了您的数据,之后的每个操作都在您的机器的内存中执行,而不是在数据库中执行。这意味着你可以很好地把它分成两个调用:

//First call. Executed as SQL query on database. Materializes data into IEnumerable<Item>
var items = MyDataContext.Items.ToList();
//second call on client
var filteredItems = Items.Where(x => x.Id == MyFunction(value1, value2));

如果你省略ToList()调用,实体框架试图将Myfunction()转换成SQL,它不能,然后抛出一个错误。