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

时间:2014-07-01 07:52:36

标签: c# linq iqueryable

我对LINQ: How to remove element from IQueryable<T>提出了类似的问题,并且大多数情况下它回答了我的问题。

我的代码设置类似:

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.NotSupportedException'类型的异常   System.Data.Entity.dll但未在用户代码中处理

     

其他信息:LINQ to Entities无法识别该方法   'Boolean MyFunction(System.Decimal,System.Decimal,System.Decimal)'   方法,并且此方法无法转换为商店表达式。“

我是linq的新手,本周刚刚开始,所以任何帮助都表示赞赏。谢谢!

3 个答案:

答案 0 :(得分:1)

您的linq查询已翻译为SQL。在这种情况下,Linq to Entities不知道如何正确地将您的方法转换为SQL。所以你不能在linq上使用自定义方法来进行sql查询。您只能使用supported methods

如果你想这样做,你必须从数据库中获取所有数据并在内存中执行此操作。

答案 1 :(得分:0)

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

我在猜测您正在查询某种数据库,但数据提供者无法翻译您的方法Myfunction

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

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

从我接受的角度来看,还需要一些额外的解释。在您确实需要之前,您的查询不会被执行。 通过调用.ToList(),您可以实现数据,之后的每个操作都会在您的计算机上的内存中执行,而不是在数据库上执行。这意味着您可以将其分成2个调用:

//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()调用,Entity Framework会尝试将Myfunction()转换为SQL,但它不能然后抛出错误。

答案 2 :(得分:0)

如果你想完美地运行这个代码,你应该像这样使用IEnumurable:

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