6
votes

Comment puis-je stocker une référence à une propriété d'objet dans un autre objet?

Ceci est une application C # Winforms.

Préface: strong> p>

Je crée un formulaire qui permettra aux utilisateurs d'importer des données à partir d'une base de données existante MySQL ou SQL Server dans Ma base de données SQL Server. Cela permet aux utilisateurs d'importer rapidement des adresses IP et d'autres données sans avoir à le rentrer à nouveau via un contrôle. P>

Exemple: strong> p>

simplifié, j'ai deux Objets, FieldObject code> et sensorObject code>. FieldObject code> existe pour stocker les noms et types de champs de base de données source et de destination. SensorObject code> est l'objet que j'ai ensuite rempli à partir des enregistrements de la base de données. Pour la simplicité, j'estime que la manipulation de type et d'autres fonctionnalités qui ne sont pas pertinentes pour la question. (Les données de Destinationfield CODE> sont limitées à une liste que je fournis à l'utilisateur et provient d'un tableau ou d'une liste dans le programme.) Voici un exemple de: P>

foreach(FieldObject f in myFieldList)
{
    mySensor(f.mySensorField) = Convert.ToString(Reader[f.DestinationField]);
}


5 commentaires

Pouvez-vous utiliser Orm pour résoudre ce problème pour ne pas avoir à écrire ce code redondant?


Object cartographie relationnelle? Je soupçonne si je n'avais pas eu à regarder ce que "ORM" était, je pourrais peut-être l'utiliser. :) Désolé, toujours novice dans la plupart de cela!


Regardez sur NHibernate: NHForge.org/wikis/howtonh/... < / a> Dans les ormes à long terme, éloignez la majeure partie de la douleur de travailler avec des bases de données relationnelles, mais ils ont besoin de travailler pour commencer.


Donc, orm :: rdbm douleur comme alcool :: inhibition ? :)


JY: En règle générale, il est préférable d'essayer d'abord la roue avant de décider de le réinventer. :-)


3 Réponses :


1
votes

En fait, la réflexion n'est pas une mauvaise idée, en particulier si vous remplissez un dictionnaire avec PropertyInfo instances pour chaque nom de propriété.


0 commentaires

2
votes

Vous devez utiliser la réflexion pour le faire. Devrait finir comme quelque chose comme: xxx

getProperties obtient une information de propriété pour chaque propriété qui peut être utilisée pour définir la valeur.

Bien sûr des infos de propriété peut être mis en cache. Il suffit de l'écrire une fois et refacteur dès qu'il court. Ne pas trop compliquer cela est appelé optimisation prématurée et conduit directement à l'enfer;)


8 commentaires

Cela semble très utile, cela aide à avoir quelqu'un qui comprend la réflexion et son utilisation pour pointer la bonne direction!


Si vous remplacez le contenu de la boucle avec lookup.add (champ.name, champ) , où lookup est un dictionnaire dictionnaire , C'est tout ce dont vous avez besoin pour cacher ces résultats pour plus tard.


Je ne suis pas clair sur ce que lecteur [myfield.destinationfield] est, mais je ne suis pas sûr de pouvoir le convertir en chaîne. Ou, si vous le faites, je penserais que vous alliez appeler simplement x.tostring () au lieu d'utiliser convert.tostring (x) .


En fait, j'ai une bibliothèque entière pour lire des trucs de SQL, mais je ne voulais pas utiliser des noms de méthodes exclusifs pour distraire de la question, alors je viens d'utiliser un espace réservé. J'aimerais avoir utilisé lecteur.getstring ("Nom de terrain") Toutefois, MS-SQL nécessite un entier (une ordinale de colonne à base de zéro) pour désigner la colonne plutôt qu'un nom de champ. Pour être clair sur l'association de noms de champ, j'ai utilisé le convert hack. :)


@Zebi: J'ai un peu de difficulté à faire fonctionner la partie Linq de votre code, j'ai récemment commencé à utiliser Linq pour travailler avec des listes (c'est un si bon outil!) Mais je ne suis pas sûr de "réparer" le .First requête. Je pensais peut-être que j'avais besoin d'essayer: var info = Sensorfields.aughle (x => x == champ.name.first (); . Je suis sûr que je peux l'obtenir éventuellement, mais je pensais que je vous donnerais la tête.


Petite mise à jour sur la partie SETVALUE, la signature correcte est la propriétéInfo.sevalue (objet, objet, objet []). Le dernier est pour les propriétés indexées (si votre propriété est une matrice et que vous souhaitez définir l'élément N TH dans le tableau. ou une clé spécifique dans un dictionnaire). Mise à jour de l'utilisation ci-dessus.


Ah Désolé, j'écris sans VS, donc aucune vérification du compilateur;) prend d'abord un prédicat qui détermine l'élément à prendre. Si vous avez une liste de numéros 1 ... 10, alors numéros.first (x => x> 5) renvoie 6. Numéros.first () Retours 1. Vous devez fournir une comparaison de champs d'appel.First (sensorfield => sensorfield.name == champ.name) devrait faire le tour.


@Zebi: Merci pour la révision. Cela fonctionne et je suis capable de passer à autre chose, merci pour l'aide.



1
votes

Vous pouvez le faire avec une réflexion. Vous obtenez la propriétéInfo de la prothèse avec le nom en question, obtenez la méthodeInfo du setter, puis l'invoque.

Cela pourrait toutefois être possible de stocker un tableau associatif (dictionnaire ou hâte ou hâte, etc.) des valeurs stockées par nom, ce qui serait beaucoup plus facile à traiter le cas échéant.


6 commentaires

Il pourrait être logique d'appeler getSetmethod sur la propriété PropertyInfo , qui renvoie un `Methodinfo 'au setter lui-même.


@Steven, à droite tu es. J'avais oublié quand l'objet mettait la mise à jour qui dans la question au moment où j'avais commencé à répondre :) Corrigé, merci.


Il suffit d'utiliser propertyInfo.setvalue (objet, objet, objet [])


@Zebi: Si nous allons mettre en cache quelque chose, pourquoi pas le Methodinfo du Setter par opposition au PropertyInfo . Je m'attends à ce que ce dernier n'utiliserait que le premier, afin que nous puissions couper une étape là-bas.


Je ne pense pas que ce changement fait une différence mesurable, mais à mon avis, il ajoute une complexité inutile. C'est la raison pour laquelle j'ai suggéré de résoudre le moyen facile sans même mettre la mise en cache. Si vous voyez des avantages sérieux hors de la mise en cache la mise en œuvre.


@Zebi, @steven. Oui, si vous alliez mettre en cache ici, la méthodeInfo serait sensible à cache, mais je ne vois pas de besoin de mettre en cache quelque chose et une bonne raison non aussi (cette cache va-t-elle grandir? Avons-nous besoin de Code LRU complexe pour empêcher de devenir massif? Si c'est le cas, cela deviendra plus lentement que le code nécessaire pour obtenir la propriétéInfo à chaque fois). Mon idée d'un dictionnaire est de ne pas cacher les infos de propriété, mais simplement pour changer les propriétés elles-mêmes pour être des paires de valeur nominale. Le mal comme une manière normale de faire des propriétés, mais raisonnable si ce type de back-name recherche est le but de la classe.