web-dev-qa-db-fra.com

LINQ to Entities ne reconnaît pas la méthode 'System.Linq.IQueryable`

Je veux exécuter ce code simple LINQ pour avoir un numéro d'enregistrement dans LINQ mais le résultat est inférieur à l'erreur

var model = _db2.Persons.Select(
    (x, index) => new 
    {
        rn = index + 1,
        col1 = x.Id
    }).ToList();

Erreur:

LINQ to Entities ne reconnaît pas la méthode 'System.Linq.IQueryable1[<>f__AnonymousType22 [System.Int32, System.Int32]] Sélectionnez [Personne, <> f__AnonymousType22](System.Linq.IQueryable1 [MvcApplication27.Models.Person], System.Linq.Expressions.Expression1[System.Func3. .Person, System.Int32, <> f__AnonymousType2`2 [System.Int32, System.Int32]]]) ', et cette méthode ne peut pas être traduite en expression de magasin.

18
ehsan

Le problème est que LINQ to Entities ne comprend pas comment convertir cette surcharge Select (celle qui vous donne l'index) en une requête SQL. Vous pouvez résoudre ce problème en sélectionnant d'abord la partie de la base de données dont vous avez besoin (pour éviter de sélectionner chaque colonne inutilement), puis en prenant AsEnumerable() pour le prendre comme un IEnumerable<T> au lieu d'un IQueryable<T>, puis en utilisant la Select uniquement en C # (en bref, IQueryable<T>s sont converties en SQL, alors que IEnumerable<T>s est exécuté dans le code).

var model = _db2.Persons.Select(x => x.Id).AsEnumerable().Select(
    (id, index) => new
    {
        rn = index + 1,
        col1 = id
    }).ToList();

Notez que la requête telle que vous la voyez semble être non ordonnée, de sorte que les paires id/index peuvent changer chaque fois que vous appelez cela. Si vous vous attendiez à une cohérence, vous devriez commander par quelque chose (par exemple, _db2.Persons.OrderBy(...)).

Modifier

Ajout du commentaire de Scott :

En tant que référence Nice voici la liste de toutes les instructions Linq intégrées dans le cadre et une liste si celle-ci est compatible ou non .

22
Tim S.

Vous pouvez simplement sélectionner l'ID et ensuite créer votre propre objet anonyme en utilisant linq to object, par exemple:

var model = _db2.Persons.Select(x => x.Id)
                        .ToList() // return int[]
                        .Select((id, index) => new
                                {
                                    rn = index + 1,
                                    col1 = id
                                 }) // return anonymous[] (with rn and col1)
                         .AsEnumerable(); // get an IEnumerable (readonly collection)

Cela est peut-être dû au fait qu'Entity Framework ne prend pas en charge ce type de requête utilisant linq comme linq pourrait le faire en mémoire. Dans ce cas, vous pouvez sélectionner uniquement ce dont vous avez besoin (id dans votre cas) et l'exécuter, à l'aide de la méthode ToList() pour concrétiser. votre requête et après cela vous aurez une liste en mémoire, vous pouvez donc utiliser linq pour les objets et utiliser la méthode supportée comme vous le souhaitez.

1
Felipe Oriani