La méthode ne peut pas être traduite en une expression de magasin

89

J'ai vu ce code fonctionner avec LINQ to SQL, mais lorsque j'utilise Entity Framework, cela génère cette erreur:

LINQ to Entities ne reconnaît pas la méthode 'System.Linq.IQueryable'1 [MyProject.Models.CommunityFeatures] GetCommunityFeatures ()', et cette méthode ne peut pas être traduite en une expression de magasin.

Le code du référentiel est le suivant:

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 est une liste qui étend la puissance d'IQueryable.

Quelqu'un pourrait-il expliquer pourquoi cette erreur se produit?

Shawn Mclean
la source

Réponses:

115

Raison: De par sa conception, LINQ to Entities nécessite que toute l'expression de requête LINQ soit traduite en requête serveur. Seules quelques sous-expressions non corrélées (expressions de la requête qui ne dépendent pas des résultats du serveur) sont évaluées sur le client avant que la requête ne soit traduite. Les invocations de méthode arbitraires qui n'ont pas de traduction connue, comme GetHomeFeatures () dans ce cas, ne sont pas prises en charge.
Pour être plus précis, LINQ to Entities ne prend en charge que les constructeurs et initialiseurs sans paramètre .

Solution: Par conséquent, pour surmonter cette exception, vous devez fusionner votre sous-requête dans la principale pour GetCommunityFeatures () et GetHomeFeatures ()au lieu d'appeler directement des méthodes à partir de la requête LINQ. De plus, il y a un problème sur les lignes que vous essayiez d'instancier une nouvelle instance de LazyList à l' aide de ses constructeurs paramétrés, comme vous auriez pu le faire dans LINQ to SQL . Pour cela, la solution serait de passer à l'évaluation client des requêtes LINQ (LINQ to Objects). Cela vous obligera à appeler la méthode AsEnumerable pour vos requêtes LINQ to Entities avant d'appeler le constructeur LazyList.

Quelque chose comme ça devrait fonctionner:

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)
       };
}


Plus d'informations: veuillez consulter LINQ to Entities, qu'est-ce qui n'est pas pris en charge? pour plus d'informations. Consultez également LINQ to Entities, des solutions de contournement sur ce qui n'est pas pris en charge pour une discussion détaillée sur les solutions possibles. (Les deux liens sont les versions mises en cache car le site Web d'origine est en panne)

Morteza Manavi
la source