Créer un Tuple dans une Linq Sélectionnez
Je travaille avec C# et .NET Framework 4.5.1 de la récupération de données à partir d'une base de données SQL Server avec Entity Framework 6.1.3.
J'ai ceci:
codes = codesRepo.SearchFor(predicate)
.Select(c => new Tuple<string, byte>(c.Id, c.Flag))
.ToList();
Et quand je le lance, j'obtiens ce message:
Seulement sans paramètre constructeurs et les initialiseurs sont pris en charge dans LINQ
à des Entités.
Je ne sais pas comment je dois créer le Tuple parce que tous les exemples que j'ai trouvé sont la plupart du temps comme celui-ci.
J'ai essayé ceci:
codes = codesRepo.SearchFor(predicate)
.Select(c => Tuple.Create(c.Id, c.Flag))
.ToList();
Et obtiens cette erreur:
LINQ to entities ne reconnaît pas la méthode
'Système.Tuple`2[Système.Chaîne,Système.Octet]
Créer[String,Byte](Système D'.String, Byte)', et cette méthode
ne peut pas être traduit dans un magasin d'expression.
Où est le problème?
- On dirait que vous aurez besoin de créer un objet fortement typé. Mais oui, bonne question; upvoted.
Vous devez vous connecter pour publier un commentaire.
Tandis que le réponse par octavioccl fonctionne, c'est mieux de le premier projet, le résultat de la requête dans un type anonyme, et puis de passer à l'énumération et à la convertir en n-uplet. De cette façon, votre requête sera de récupérer à partir de la base de données uniquement les champs nécessaires.
.Select(c => new { c.Id, c.Flag, c.Foo?.Code })
ne fonctionne pas.?.
n'est pas pris en charge dans des arbres d'expression. Mais dans les autres cas, vous pouvez étendre la anonyme de type avec autant de valeurs que vous voulez - tout ne t oubliez pas de nom en cas de besoin 🙂 par exemplec => new { c.Id, c.Flag, Code = (int?)c.Foo.Code }
Juste une mise à jour de réponse pour le C# 7, maintenant vous pouvez utiliser une syntaxe plus simple pour créer ValueTuples.
Vous pouvez même nom les propriétés de la n-uplet maintenant:
Ainsi, au lieu de l'utiliser comme Item1 ou Item2 vous pouvez y accéder comme Id ou le Drapeau.
Essayez ceci:
Été informé que ce n'est pas accepter dans LINQ to entities.
Une autre option serait de tirer le résultat dans la mémoire avant de choisir. Si vous allez faire cela, je vous recommande de les faire tous de la filtrer avant de la .AsEnumerable (), car il signifie que vous êtes seulement en tirant les résultats que vous voulez plutôt que de le tirer de l'ensemble de la table et le filtrage.
ainsi Tuple.Créer(c.Id, c.Drapeau) pourrait être modifié à nouveau Tuple(c.Id, c.Drapeau) si vous voulez rendre le code un peu plus explicite dans les tuples types
Dans linq to entities vous pouvez projeter sur un type anonyme ou sur un DTO.Pour éviter ce problème, vous pouvez utiliser
AsEnumerable
méthode d'extension:Cette méthode permet de travailler avec des Linq to Object au lieu Linq to entities, donc après l'appel,vous pouvez projeter le résultat de votre requête dans ce que vous avez besoin.L'avantage de l'utilisation de
AsEnumerable
au lieuToList
est queAsEnumerable
ne pas exécuter la requête, il préserve l'exécution différée. C'est une bonne idée toujours filtrer vos données avant d'appeler l'une de ces méthodes.J'ai trouvé la réponse:
Utiliser cette méthode pour ce faire et à l'utilisation de l'asynchrone.
Juste mes deux cents: cela m'a pris un peu de temps, avec les noms de type:
Quelques noddy exemples:
Ce qui concerne.
public (string Id, byte Flag) SearchFor(Expression predicate)
, mais c'est à côté de la question. Deux cents ne devrait pas être une réponse, mais un commentaire.