web-dev-qa-db-fra.com

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

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

LINQ to Entities ne reconnaît pas la méthode 'System.Linq.IQueryable'1 [MyProject.Models.CommunityFeatures] GetCommunityFeatures ()' et ne peut pas être traduite dans 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 le pouvoir d'IQueryable.

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

85
Shawn Mclean

Raison: De par sa conception, LINQ aux entités requiert que l'expression de requête LINQ complète soit traduit en une requête du 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 la traduction de la requête. Les invocations de méthodes 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 supporte que Constructeurs sans paramètre et Initializers.

Solution: Par conséquent, pour surmonter cette exception, vous devez fusionner votre sous-requête dans la requête 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 en utilisant ses constructeurs paramétrés, comme vous le feriez peut-être dans LINQ to SQL. Pour cela, la solution serait de passer à l’évaluation des requêtes LINQ par le client (LINQ to Objects). Cela nécessite que vous appeliez la méthode AsEnumerable pour vos requêtes LINQ to Entities avant d'appeler le constructeur LazyList.

Quelque chose comme ça devrait marcher:

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'infos: Veuillez regarder LINQ to Entities, qu'est-ce qui n'est pas supporté? = pour plus d'informations. Consultez également LINQ to Entities, solutions de rechange pour ce qui n’est pas pris en charge pour une discussion détaillée des solutions possibles. (Les deux liens sont les versions en cache car le site Web d'origine est en panne)

110
Morteza Manavi