El método no se puede traducir a una expresión de tienda

89

Vi que este código funcionaba con LINQ to SQL, pero cuando uso Entity Framework, arroja este error:

LINQ to Entities no reconoce el método 'System.Linq.IQueryable'1 [MyProject.Models.CommunityFeatures] GetCommunityFeatures ()', y este método no se puede traducir a una expresión de tienda.

El código del repositorio es este:

public IQueryable<Models.Estate> GetEstates()
{
    return from e in entity.Estates
           let AllCommFeat = GetCommunityFeatures()
           let AllHomeFeat = GetHomeFeatures()
           select new Models.Estate
                      {
                                EstateId = e.EstateId,
                                AllHomeFeatures = new LazyList<HomeFeatures>(AllHomeFeat),
                                AllCommunityFeatures = new LazyList<CommunityFeatures>(AllCommFeat)
                      };
}

public IQueryable<Models.CommunityFeatures> GetCommunityFeatures()
{
    return from f in entity.CommunityFeatures
           select new CommunityFeatures
                      {
                          Name = f.CommunityFeature1,
                          CommunityFeatureId = f.CommunityFeatureId
                      };
}

public IQueryable<Models.HomeFeatures> GetHomeFeatures()
{
    return from f in entity.HomeFeatures
           select new HomeFeatures()
           {
               Name = f.HomeFeature1,
               HomeFeatureId = f.HomeFeatureId
           };
}

LazyList es una lista que amplía el poder de IQueryable.

¿Alguien podría explicar por qué ocurre este error?

Shawn Mclean
fuente

Respuestas:

115

Motivo: por diseño, LINQ to Entities requiere que toda la expresión de consulta LINQ se traduzca a una consulta de servidor. Solo unas pocas subexpresiones no correlacionadas (expresiones de la consulta que no dependen de los resultados del servidor) se evalúan en el cliente antes de traducir la consulta. Las invocaciones de métodos arbitrarios que no tienen una traducción conocida, como GetHomeFeatures () en este caso, no son compatibles.
Para ser más específicos, LINQ to Entities solo admite inicializadores y constructores sin parámetros . Solución: Por lo tanto, para superar esta excepción, debe fusionar su subconsulta en la principal para GetCommunityFeatures () y GetHomeFeatures ()

en lugar de invocar métodos directamente desde dentro de la consulta LINQ. Además, hay un problema en las líneas de que estaba intentando crear una instancia nueva de LazyList usando sus constructores parametrizados, tal como podría haber estado haciendo en LINQ to SQL . Para eso, la solución sería cambiar a la evaluación del cliente de las consultas LINQ (LINQ to Objects). Esto requerirá que invoques el método AsEnumerable para tus consultas de LINQ to Entities antes de llamar al constructor LazyList.

Algo como esto debería funcionar:

public IQueryable<Models.Estate> GetEstates()
{
    return from e in entity.Estates.AsEnumerable()
       let AllCommFeat = from f in entity.CommunityFeatures
                         select new CommunityFeatures {
                             Name = f.CommunityFeature1,
                             CommunityFeatureId = f.CommunityFeatureId
                         },
       let AllHomeFeat = from f in entity.HomeFeatures
                         select new HomeFeatures() {
                             Name = f.HomeFeature1,
                             HomeFeatureId = f.HomeFeatureId
                         },
       select new Models.Estate {
            EstateId = e.EstateId,
            AllHomeFeatures = new LazyList<HomeFeatures>(AllHomeFeat),
            AllCommunityFeatures = new LazyList<CommunityFeatures>(AllCommFeat)
       };
}


Más información: Eche un vistazo a LINQ to Entities, ¿qué no es compatible? para más información. Consulte también LINQ to Entities, Workarounds sobre lo que no es compatible para una discusión detallada sobre las posibles soluciones. (Ambos enlaces son las versiones en caché porque el sitio web original no funciona)

Morteza Manavi
fuente