2011-12-10 47 views
3

在一般情况下,如果创建作用于实体的扩展方法:可以扩展LINQ-To-Entities吗?

public static MyEntity Foo(this MyEntity entity) 
{ 
    // do something to the entity 
} 

一个不能直接在投影使用此从LINQ到等实体如下:

var result = myContext.MyEntities.Select(x=> x.Foo()); 

否则这样产生的误差,例如:

System.NotSupportedException:LINQ实体无法识别 方法“富(myEntity所)”方法,和这种方法不能将 翻译成商店表达。

我完全理解为什么会出现此错误。我的问题是:如果我可以提供使用表达式树的Foo的实现,有什么方法可以将Foo添加到LINQ-to-entities可以理解的操作中?如果是这样 - 如何?


注:我当然可以将其转换为像这样的列表:

var result = myContext.MyEntities.ToList().Select(x=> x.Foo()); 

,并没有错误。但我不再拥有IQueryable。我有一个IEnumerable。如果我是这样使用它:

var result = myContext.MyEntities.ToList().Select(x=> x.Foo()).First(); 

我最终会取录取前一个和丢弃其余前所有实体 - 这将是可怕的性能。

+1

您可以编写自己的IQueryProvider,包装EF的查询提供程序,识别调用Foo的表达式,并为EF提供一系列可翻译为支持存储(例如SQL)语言的等效表达式。但这并没有多少乐趣,也不是普遍的。无论如何,“Foo”做了什么? – dasblinkenlight

+0

它的作用并不重要,这就是为什么我将它称为Foo的原因。我有这样的东西需要一些不同的需求,而且只是在寻找钩子。我喜欢关于包装EF查询提供者的想法。你能提供一个例子吗?谢谢! –

+1

请参阅:[如何包装实体框架拦截LINQ表达式执行之前?](http://stackoverflow.com/questions/1839901/how-to-wrap-entity-framework-to-intercept-the-linq-表达式只是在执行前) – Ani

回答

2

使用LINQKit项目,而不是你的方法foo,你将被迫编写相当的表达式树。

+0

整洁的图书馆 - 但所有的例子显示增加条款where条款。你能否提供一个例子来执行select语句中的投影,就像我的Foo需要做的那样? –

+1

试试这个:Expression > test =(x)=> x; var result = context.Collection_Of_TEntity.AsExpandable()。Select(x => test.Invoke(x))。ToList(); – Mic

+0

这几乎是我最初的要求。谢谢! –