使用自定义函数过滤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的新手,这周才开始,所以任何帮助都很感激。谢谢!
您的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,它不能,然后抛出一个错误。