Est-il possible de déclarer un type anonyme en C # avec un ensemble de champs variable / dynamique?
En C#, je voudrais savoir si il est possible de déclarer un type anonyme où les champs ne sont connus qu'au moment de l'exécution.
Par exemple, si j'ai une Liste de paires clé/valeur, puis-je déclarer un type anonyme basé sur le contenu de cette liste? Le cas spécifique, je travaille avec passage de paramètres à Dapper, où je ne sais pas à l'avance combien de paramètres, je vais avoir.
List<Tuple<string, string>> paramList = new List<Tuple<string, string>>() {
new Tuple<string, string>("key1", "value1"),
new Tuple<string, string>("key2", "value2")
...
};
Je voudrais convertir cette Liste (ou un équivalent de la Carte) dans un type anonyme que je peux passer à Dapper, comme les paramètres de la requête. Donc, idéalement, la liste ci-dessus liquidation à la recherche de ce genre, si elle est définie comme un type anonyme:
new { key1=value1, key2=value2, ... }
J'ai vu plusieurs questions sur StackOverflow de demander à propos de l'extension de les types anonymes après qu'ils ont été déclarés ("extendo objets"), ou la déclaration d'arbitraire champs d'un objet après sa création, mais je n'ai pas besoin de le faire... j'ai juste besoin de déclarer les types de manière dynamique à l'avant une fois. Mon soupçon est qu'il faudra un peu de fantaisie à la réflexion, si c'est possible.
Ma compréhension est que le compilateur définit un type anonyme pour les classes de sous le capot à la compilation, donc les champs de cette classe ne sont pas disponibles jusqu'à ce moment de l'exécution, je suis peut-être hors de la chance. Mon cas d'utilisation peut en effet pas être différent en réalité que d'utiliser un "extendo objet" de définir arbitraire des champs, à chaque fois.
Sinon, si quelqu'un connaît une meilleure façon de passer les paramètres de requête de Dapper (plutôt que de déclarer une classe anonyme), j'aimerais entendre à ce sujet ainsi.
Merci!
Mise à JOUR
Désolé pour le retard dans le retour à celui-ci! Ces réponses ont été de tous les grands, je souhaite que je pourrais donner des points à tout le monde. J'ai fini par utiliser jbtule de la solution (à modifier par Sam Safran), en passant IDynamicParameters à Dapper, donc j'ai senti que j'avais à donner une réponse à lui. Les autres réponses ont également été bonne, et a répondu à certaines questions que j'avais posées. J'apprécie vraiment tout le monde de temps en temps sur ce!
source d'informationauteur Egahn
Vous devez vous connecter pour publier un commentaire.
Dapper créateurs étaient très conscients de ce problème. Ce type de fonctionnalité est vraiment nécessaire pour
INSERT
etUPDATE
aides.La
Query
Execute
etQueryMultiple
méthodes prennent endynamic
paramètre. Cela peut être soit un type anonyme, un type de béton ou d'un objet qui implémenteIDynamicParameters
.Cette interface est très pratique,
AddParameters
est appelée juste avant l'exécution du SQL. Non seulement cela vous donne contrôle complet sur les paramètres envoyés à SQL. Il permet de raccorder DB spécifiques DbParameters, puisque vous avez accès à la commande (vous pouvez la lancer à la base de données spécifique). Cela permet de soutenir des Valeurs de la Table de Paramètres et ainsi de suite.Dapper contient une implémentation de cette interface qui peut être utilisé pour des fins appelé
DynamicParameters
. Cela vous permet à la fois concaténées anonyme paramètre sacs et ajouter des valeurs spécifiques.Vous pouvez utiliser la méthode AddDynamicParams pour ajouter un type anonyme.
Les types anonymes sont générées par le compilateur. Vous voulez savoir si le compilateur va générer un générées par le compilateur type avec les types de champ pas connu du compilateur. De toute évidence, elle ne peut pas le faire; comme vous l'avez deviner, vous êtes hors de la chance.
Nous avons l'habitude d'appeler ces "expando" des objets.
Si ce que vous voulez faire est de prendre un expando objet basé sur un dictionnaire de paires clé-valeur, puis utilisez le ExpandoObject classe de le faire. Voir cet article MSDN pour plus de détails:
http://msdn.microsoft.com/en-us/magazine/ff796227.aspx
Si ce que vous voulez faire est de générer un véritable .NET de la catégorie au moment de l'exécution, vous pouvez le faire aussi. Comme vous l'avez remarque, vous avez besoin d'un peu de fantaisie à la réflexion de le faire. Ce que vous voulez faire est de faire une collection de montage (soi-disant parce que contrairement à un montage normal, vous générer lors de l'exécution et le garbage collector propre quand vous avez fini avec elle.)
Voir http://msdn.microsoft.com/en-us/library/dd554932.aspx pour plus de détails sur la façon de faire une collection de montage et émettent un type à l'aide d'un TypeBuilder.
Vous ne pouvez pas utiliser un type anonyme. Les types anonymes sont générés par le compilateur plutôt qu'au moment de l'exécution. Vous pourrait certainement utiliser
dynamic
:Vous pouvez ensuite utiliser dynamicObj comme un objet normal: