一般来说,如果我创建一个作用于实体的扩展方法:
这样做会产生如下错误:
注意:我当然可以像这样将其转换为列表:
public static MyEntity Foo(this MyEntity entity)
{
// do something to the entity
}
不能直接在Linq-To-Entities的投影中使用,例如以下方式:
var result = myContext.MyEntities.Select(x=> x.Foo());
这样做会产生如下错误:
我完全理解为什么会出现这种错误。我的问题是:如果我可以提供一个使用表达式树的Foo实现,是否有办法将Foo添加到LINQ-to-entities所理解的操作中呢?如果有,怎么做?System.NotSupportedException: LINQ to Entities does not recognize the method 'Foo(MyEntity)' method, and this method cannot be translated into a store expression.
注意:我当然可以像这样将其转换为列表:
var result = myContext.MyEntities.ToList().Select(x=> x.Foo());
它没有出现错误。但是我不再拥有IQueryable,而是拥有IEnumerable。如果我像这样使用它:
var result = myContext.MyEntities.ToList().Select(x=> x.Foo()).First();
如果我在获取顶部实体之前获取所有实体,然后丢弃其余的实体,这会对性能造成极大的影响。
Foo
到底是做什么的呢? - Sergey KalinichenkoFoo
的作用非常重要,因为你能否将逻辑推入底层数据存储取决于它。最终,你的实现将在RDBMS中执行Foo
的逻辑,或者将所有内容拉入内存并在CLR中运行Foo
(基本上,与你示例中的ToLost
使用相同的代码路径)。然而,通常情况下,EF会给你很多非常有用的扩展点,你应该在考虑自己的IQueryProvider包装器之前先考虑这些扩展点。 - Sergey Kalinichenko