Créer un tuple dans une sélection Linq

Je travaille avec C # et .NET Framework 4.5.1 pour récupérer des données d’une firebase database SQL Server avec Entity Framework 6.1.3.

J’ai ceci:

codes = codesRepo.SearchFor(predicate) .Select(c => new Tuple(c.Id, c.Flag)) .ToList(); 

Et quand je le lance, je reçois ce message:

Seuls les constructeurs et les initialiseurs sans paramètre sont pris en charge dans LINQ to Entities.

Je ne sais pas comment je dois créer le tuple parce que tous les exemples que j’ai trouvés sont pour la plupart comme celui-ci.

J’ai essayé ceci:

 codes = codesRepo.SearchFor(predicate) .Select(c => Tuple.Create(c.Id, c.Flag)) .ToList(); 

Et obtenez cette erreur:

LINQ to Entities ne reconnaît pas la méthode ‘System.Tuple`2 [System.Ssortingng, System.Byte] Create [Ssortingng, Byte] (System.Ssortingng, Byte)’ et cette méthode ne peut pas être traduite en expression de magasin.

Où est le problème?

Bien que la réponse par octavioccl fonctionne, il est préférable de projeter d’abord le résultat de la requête en type anonyme, puis de basculer en énumérable et de le convertir en tuple. De cette façon, votre requête récupérera de la firebase database uniquement les champs nécessaires.

 codes = codesRepo.SearchFor(predicate) .Select(c => new { c.Id, c.Flag }) .AsEnumerable() .Select(c => new Tuple(c.Id, c.Flag)) .ToList(); 

Essaye ça:

 codes = codesRepo.SearchFor(predicate) .Select(c => Tuple.Create(c.Id, c.Flag)) .ToList(); 

Être informé que cela n’accepte pas dans LINQ aux entités.

Une autre option serait d’extraire le résultat en mémoire avant de le sélectionner. Si vous envisagez de le faire, je vous recommande de faire tout le filtrage avant .AsEnumerable (), car cela signifie que vous ne récupérez que les résultats souhaités, par opposition à la suppression de la totalité de la table, puis au filtrage.

 codes = codesRepo.SearchFor(predicate).AsEnumerable() .Select(c => Tuple.Create(c.Id, c.Flag)) .ToList(); 

De même, Tuple.Create (c.Id, c.Flag) peut être remplacé par le nouveau Tuple (c.Id, c.Flag) si vous souhaitez rendre le code un peu plus explicite dans les types de tuples.

Dans linq to entités, vous pouvez projeter sur un type anonyme ou sur un DTO. Pour éviter ce problème, vous pouvez utiliser la méthode d’extension AsEnumerable :

 codes = codesRepo.SearchFor(predicate).AsEnumerable(). .Select(c => new Tuple(c.Id, c.Flag)) .ToList(); 

Cette méthode vous permet de travailler avec Linq to Object au lieu de Linq to Entities . Ainsi, après l’appeler, vous pouvez projeter le résultat de votre requête dans le contenu souhaité. exécution différée. C’est une bonne idée de toujours filtrer vos données avant d’appeler l’une de ces méthodes.

J’ai trouvé la réponse:

 codes = codesRepo.SearchFor(predicate) .ToList() .Select(c => Tuple.Create(c.Id, c.Flag)) .ToList(); 

Utilisez cette méthode pour cela et utilisez le code asynchrone.

 var codes = await codesRepo.SearchFor(predicate) .Select(s => new { Id = s.Id, Flag = s.Flag }).FirstOrDefaultAsync(); var return_Value = new Tuple(codes.Id, codes.Flag);