2010-01-11 21 views
8

se han topado con este problema:Teniendo en cuenta LINQ to Entities no es compatible con "Métodos personalizados", ¿cómo te quedas seco?

Custom Methods & Extension Methods cannot be translated into a store expression

Básicamente tengo algunas consultas LINQ complicados, por lo que quería descomponerlas en sub consultas que se implementan como métodos que devuelven IQueryables. Mi esperanza era que estas IQueryables pudieran componerse juntas en una declaración LINQ (como estoy seguro de que puedes hacer en LINQ to SQL).

El problema es que si se intenta esto se obtiene (por ejemplo):

LINQ a Entidades no reconoce el método 'System.Linq.IQueryable`1 [hilo] GetThreadsByMostReccentlyPosted (Int32) ' método, y este método no puede ser traducido a una expresión de tienda.

Me parece muy importante que si usa un LINQ ORM, entonces deba ser capaz de redactar consultas LINQ. De lo contrario, cualquier lógica de consulta común debe copiarse & pegada.

Dada esta limitación, ¿cómo se supone que debo permanecer SECO con LINQ para Entidades?

+0

así que lo que realmente quieres saber es "¿Cómo hago la ejecución retrasada en EF, como puedo en L2S?". –

+0

la única forma en que puedo ver esto hasta ahora es convertir mi IQueryable en IEnumerable, en cuyo punto sospecho que usted pierde la capacidad de generar una declaración SQL óptima – Schneider

+0

No, nada que ver con la ejecución retrasada. Básicamente no me deja escribir sentencias de linq que incluyen los métodos – Schneider

Respuesta

12

dos maneras:

  1. métodos que devuelvan expresiones se pueden utilizar
  2. separar el consultables y los bits enumerables

Para # 1, tenga en cuenta:

public Expression<Func<Foo, bool>> WhereCreatorIsAdministrator() 
{ 
    return f => f.Creator.UserName.Equals("Administrator", StringComparison.OrdinalIgnoreCase); 
} 

public void DoStuff() 
{ 
    var exp = WhereCreatorIsAdministrator(); 
    using (var c = new MyEntities()) 
    { 
     var q = c.Foos.Where(exp); // supported in L2E 
     // do stuff 
    } 
} 

Para una ejemplo del número 2, lea este artículo: How to compose L2O and L2E queries. Considere el ejemplo dado allí:

var partialFilter = from p in ctx.People 
        where p.Address.City == “Sammamish” 
        select p; 

var possibleBuyers = from p in partiallyFilter.AsEnumerable() 
        where InMarketForAHouse(p); 
        select p; 

Esto podría ser menos eficiente, o puede estar bien. Depende de lo que estés haciendo. Por lo general, está bien para las proyecciones, a menudo no está bien para las restricciones.

Actualización Acabo de ver an even better explanation of option #1 de Damien Guard.

+0

Prefiero la opción uno. [Escribí un blog sobre este mismo tema] (http://www.codetunnel.com/blog/post/64/how-to-simplify-complex-linq-expressions) porque tenía algunas expresiones LINQ locamente complejas que estaban recibiendo difícil de mantener Algo tenía que hacerse. – Chev

0

EF no puede redactar una consulta a partir de una expresión LINQ que incluya un método. EF necesita valores literales para componer el SQL.

Tendrá que conformarse con consultas "comunes" que devuelven un superconjunto de las entidades que necesita para un caso determinado, luego utilice métodos de extensión y LINQ para restringir el conjunto de resultados una vez que se ha devuelto desde la base de datos.

+0

¿te refieres a IEnumerables cuando dices "Consultas comunes"? p.ej. algo que tiene un conjunto de resultados en lugar de un IQueryable? – Schneider

+0

Por "consultas comunes" me refiero a consultas parametrizadas que se pueden usar para devolver superconjuntos de tamaño manejable de las entidades que desea. Las consultas que diseñe dependerán de sus datos y de cuánto tenga. –

+0

Ya veo. Pero esto implica en la unión de la memoria, etc. – Schneider

Cuestiones relacionadas