2010-06-01 7 views
4

J'ai juste eu un problème lié à NHibernate où j'ai oublié de mapper une propriété d'une classe.Comment trouver des propriétés non mappées dans une classe mappée NHibernate?

Un exemple très simplifié:

public class MyClass 
{ 
    public virtual int ID { get; set; } 
    public virtual string SomeText { get; set; } 
    public virtual int SomeNumber { get; set; } 
} 

... et le fichier de mapping:

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
        assembly="MyAssembly" 
        namespace="MyAssembly.MyNamespace"> 

    <class name="MyClass" table="SomeTable"> 
     <property name="ID" /> 
     <property name="SomeText" />  
    </class> 

</hibernate-mapping> 

Dans cet exemple simple, vous pouvez voir le problème à la fois:
il y a une propriété nommé "SomeNumber" dans la classe, mais pas dans le fichier de mappage. Donc, NHibernate ne le mappera pas et il sera toujours égal à zéro. La vraie classe avait beaucoup plus de propriétés, donc le problème n'était pas aussi facile à voir et il m'a fallu beaucoup de temps pour comprendre pourquoi SomeNumber renvoyait toujours zéro même si j'étais sûr à 100% que la valeur dans la base de données était! = zéro.

Alors, voici ma question:

est-il un moyen simple de trouver ce via NHibernate?
Comme un avertissement du compilateur lorsqu'une classe est mappée, mais que certaines de ses propriétés ne le sont pas.
Ou une requête que je peux exécuter et qui montre des propriétés non mappées dans des classes mappées ... vous avez l'idée.

(De plus, ce serait bien si je pouvais exclure des colonnes existantes que je vraiment ne veux pas mappée.)

EDIT:
Ok, je regardais tout ce que vous avez proposé et décidé aller avec l'API méta-données ... qui semble la plus facile à comprendre pour moi. Maintenant que je sais ce qu'il faut rechercher, j'ai trouvé quelques exemples qui m'ont aidé à démarrer.
Jusqu'à présent, j'ai ceci:

Type type = typeof(MyClass); 

IClassMetadata meta = MySessionFactory.GetClassMetadata(type); 

PropertyInfo[] infos = type.GetProperties(); 

foreach (PropertyInfo info in infos) 
{ 
    if (meta.PropertyNames.Contains(info.Name)) 
    { 
     Console.WriteLine("{0} is mapped!", info.Name); 
    } 
    else 
    { 
     Console.WriteLine("{0} is not mapped!", info.Name); 
    } 
} 

Il a presque œuvres, sauf une chose: IClassMetadata.PropertyNames renvoie les noms de toutes les propriétés sauf l'ID.
Pour obtenir l'ID, je dois utiliser IClassMetadata.IdentifierPropertyName. Oui, je pourrais enregistrer .PropertyNames dans un nouveau tableau, ajouter .IdentifierPropertyName et rechercher ce tableau.
Mais cela me semble étrange.
Y a-t-il un meilleur moyen d'obtenir toutes les propriétés mappées y compris l'ID?

+0

J'ai écrit un "testeur de cartographie" pour exactement cette raison. Mais c'est beaucoup de code. il teste si l'entité peut être stockée et récupérée sans perte de données. Peut-être que je reçois l'admission et trouve le temps de la libérer un jour. –

+0

+1 pour m'avoir montré comment obtenir le IdentifierPropertyName. Exactement ce que je cherchais! –

Répondre

5

Vous pouvez utiliser l'API de métadonnées NHibernate pour trouver les propriétés mappées et la réflexion pour trouver toutes les propriétés.

Editer Non, il n'y a pas d'autre moyen de lister toutes les propriétés, y compris l'ID.Il est pas difficile à utiliser:

foreach (PropertyInfo info in infos) 
{ 
    if (meta.PropertyNames.Contains(info.Name) || info.Name = meta.IdentifierPropertyName) 
    { 
     Console.WriteLine("{0} is mapped!", info.Name); 
    } 
    else 
    { 
     Console.WriteLine("{0} is not mapped!", info.Name); 
    } 
} 
+0

Nous faisons cela, cela n'arrive qu'une seule fois à app-init et vider les résultats sur un journal – Jaguar

+0

L'API meta-data sonne bien ... J'ai essayé de l'utiliser, mais j'ai rencontré un problème (voir ci-dessus, j'ai édité mon question). –

+0

Oh oui, vous avez raison - c'est vraiment simple. C'est dommage que je n'y ai pas pensé moi-même :-) –

1

Il y a deux outils que je connais qui peuvent aider à cela:

mais ils ne traitent pas spécifiquement le problème que vous aviez avec une propriété non mappée. La meilleure solution consiste à écrire de bons tests unitaires qui garantissent la persistance des propriétés que vous souhaitez conserver. C'est fastidieux mais nécessaire.

Questions connexes