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


Vi que este código funciona 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 extiende el poder de IQueryable.

¿Podría alguien explicar por qué ocurre este error?


74
2017-10-02 17:09


origen


Respuestas:


Razón: Por diseño, LINQ a entidades requiere que toda la expresión de consulta LINQ se traduzca en una consulta del servidor. Solo unas pocas subexpresiones no correlacionadas (expresiones en la consulta que no dependen de los resultados del servidor) se evalúan en el cliente antes de que se traduzca 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ífico, LINQ to Entities solo admite Constructores paramétricos y Inicializadores.

Solución: Por lo tanto, para superar esta excepción, debe fusionar su consulta secundaria en la principal para GetCommunityFeatures () y GetHomeFeatures () en lugar de invocar directamente métodos desde dentro de la consulta LINQ. Además, hay un problema en las líneas que intentaba crear una nueva instancia de Lista de espera usando sus constructores parametrizados, tal como podrías haber estado haciendo en LINQ a SQL. Para eso, la solución sería cambiar a la evaluación del cliente de consultas LINQ (LINQ to Objects). Esto requerirá que invoque el AsEnumerable método para 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: Por favor, eche un vistazo a LINQ to Entities, ¿qué no es compatible? para más información. También echa un vistazo LINQ to Entities, Workarounds en lo que no es compatible para una discusión detallada sobre las posibles soluciones. (Ambos enlaces son versiones en caché porque el sitio web original está caído)


102
2017-10-03 15:01