Dynamique requête Linq - comment puis-je construire la clause select?
Je suis en train de faire quelques tests avec Dynamique de Linq pour le moment, mais étant nouveau, je vais avoir des ennuis.
Actuellement, j'ai un objet DataTable que j'ai complété par une requête SQL à une base de données. Maintenant, je veux exécuter dynamique des requêtes linq sur ce DataTable. Cela peut sembler illogique, mais mon objectif final est de pouvoir effectuer des jointures sur deux tables de données qui sont remplies par les deux bases de données différentes, donc, avec cela à l'esprit, j'espère qu'il fait plus de sens.
J'essaie de comprendre une situation plus simple et expérimenter un peu avec elle avant d'aller de l'avant pour résoudre ce problème.
Question est que je ne suis pas entièrement sûr de savoir le choix entre IQueryable(T) et IEnumerable(Of T). La façon dont je le comprends, c'est que si vous faites tout dans le mémoire que vous choisissez IEnumerable. Je pense que, s'adapte pour mon cas, non? Cependant, quand j'ai regardé la modification de la IEnumerable dans IQuerbyable (dans l'extrait de code ci-dessous), j'ai été surpris de voir que la "x.Élément(Fieldname)" ne fonctionne pas!? Ce qui me manque? L'erreur qu'il a donné est: "la Fin des opérations de Liaison ne peut pas être converti à une Arborescence d'Expression".
De toute façon, permet de jeter un coup d'oeil. J'ai déjà une partie de ce travail:
Dim desc As String = "Description"
Dim status As String = "Status"
Dim query As IEnumerable(Of DataRow) = From x In tab.AsEnumerable()
query = query.Where(Function(x As Object) x.Item(status) < 100)
For Each row As DataRow In query.ToList()
'Do something
Next row
Cela semble bien fonctionner. J'ai utilisé les deux variables de chaîne, parce que dans la fin, je veux dynamiquement décider du domaine à prendre. Alors, "x!Description" n'est pas la voie à suivre pour moi. Cependant, maintenant, je voulais ajouter une projection de la requête, c'est à dire de Sélectionner un certain nombre de colonnes.Mon espoir était que cela doit fonctionner comme ceci:
query = query.Select(Of String)(Function(x As Object) x.Item(desc))
(N. B.: j'utilise Select(De la Chaîne), parce que cette colonne a que comme un type. Cela devrait bien sûr, en fin de compte être dynamiquement rempli trop)
Toutefois, il échoue en cours d'exécution sur un InvalidCastException: "Impossible de convertir l'objet de type 'WhereSelectEnumerableIterator2[System.Data.DataRow,System.String]' to type 'System.Collections.Generic.IEnumerable
1[Système.Les données.DataRow]'." Je n'ai pas vraiment comprendre ce qui se passe ici; je devine que quelque chose est faux, parce que je veux retourner DataRow, mais pour le moment uniquement sélectionner un champ, qui se trouve être une Chaîne de caractères. Quelqu'un peut-il expliquer et m'aider?
Merci d'avance!
OK, MODIFIER, comme je devrais probablement avoir donné quelques infos à partir de zéro:
Je pourrais avoir un nombre variable d'où - ou sélectionnez-les clauses. Mon idée était que je pouvais ajouter dynamiquement en parcourant la liste qui contient cette information. Alors j'ai pensé que j'ai un peu besoin de la .Où() et .Sélectionnez() les fonctions qui IEnumerable offre.
OriginalL'auteur Martao | 2012-08-21
Vous devez vous connecter pour publier un commentaire.
Vous déclarez
query
pour être de typeIEnumerable(Of DataRow)
dans la ligne suivante:Maintenant, vous voulez créer un
IEnumerable(Of String)
avec votreSelect
, ce qui est bien.Mais vous essayez d'assigner le résultat, qui est de type
IEnumerable(Of String)
, àquery
, qui est de typeIEnumerable(Of DataRow)
.Et depuis
IEnumerable(Of String)
ne peut pas être lancée àIEnumerable(Of DataRow)
et vice versa, vous obtenez uneInvalidCastException
.Aussi, je ne sais pas pourquoi vous utilisez
Function(x As Object)
dans votreWhere
etSelect
, de mieux utiliser lesFunction(row As DataRow)
, puisque vous savez déjà que vous travaillez avec unDataRow
.En outre, votre code peut être réécrite comme ceci:
Changer
columnToUse
vous ferait mesure d'sélectionnez le champ que vous souhaitez de manière dynamique.Pour sélectionner plus d'un domaine, vous devez retourner une collection de Dictionarys, ExpandoObjects ou n-Uplets ou quelque chose comme ça.
Exemple:
Pour répondre à l'autre partie si votre question: Oui, utilisation
IEnumerable
ici, puisque vous travaillez déjà sur un en mémoireDataTable
.Aussi, j'étais conscient de la réécriture de vous montrer, mais ce n'est pas ce que je veux. La raison est que je voudrais potentiellement créer l'interface IEnumerable par une boucle for. Par exemple, j'ai pu avoir les champs à sélectionner dans une liste, et de Créer le Sélectionner dans une boucle For. Ou je pourrais avoir une quantité variable de clauses where et les ajouter à l'aide d'une boucle for. Donc, quelque chose comme ce pseudo-code: Pour chaque champ dans la Liste query = requête.Sélectionnez(champ Comme champ.type de) champ Suivant
J'ai ajouté deux exemples de sélectionner plus d'un domaine dynamique. Notez que vous devez retourner une colletion de dictionnaires ou quelque chose comme cela pour ce travail. Plusieurs
Where
clauses ne devraient pas être un problème, puisque la chaîne ne devrait pas modifier le type de données obtenu comme unSelect
de projection.Merci pour les suggestions. J'ai essayé la première solution et ai eu de travail. Certainement, cela me permet d'aller plus loin. ExpandoObject est aussi très intéressant de construire que je n'avais jamais entendu parler avant. D'autres questions peuvent apparaître, mais cette question est principalement answerred, je suppose. Merci encore.
OriginalL'auteur sloth