2009-06-30 9 views
3

Est-il possible de faire une sorte de conversion de type et de mapper directement à System.Drawing.Color? Je stocke les couleurs en tant que valeurs html/css. c'est-à-dire #ffffff. Je ne veux pas avoir à créer un type personnalisé qui implémente IUserType, c'est juste un wrapper pour System.Drawing.Color.NHibernate Mapping à System.Drawing.Color

+0

Pourquoi ne voulez-vous pas créer un type d'utilisateur pour cela? Il fait exactement ce que vous essayez de faire ... –

+0

David - La raison en est qu'il existe déjà un type, System.Drawing.Color, qui peut être utilisé. Pourquoi recréer ce type? –

+2

Un type d'utilisateur NHibernate ne remplace pas ce type, il ne fait que mettre en œuvre la logique pour traduire un champ de base de données dans ce type. Vous mappez en utilisant le type, vous stockez une chaîne dans la base de données et vous exposez votre propriété en tant que System.Drawing.Color. Est-ce que le code postal ... –

Répondre

6

Essayez ceci pour la taille. Un type d'utilisateur NHibernate ne remplace pas le type que vous voulez exposer, il fournit simplement le mécanisme pour mapper automatiquement du type de base de données stocké au type .NET (ici, de la chaîne à la couleur et vice versa).

public class ColorUserType : IUserType 
{ 
    public bool Equals(object x, object y) 
    { 
     if (ReferenceEquals(x, y)) return true; 
     if (x == null || y == null) return false; 
     return x.Equals(y); 
    } 

    public int GetHashCode(object x) 
    { 
     return x == null ? typeof(Color).GetHashCode() + 473 : x.GetHashCode(); 
    } 

    public object NullSafeGet(IDataReader rs, string[] names, object owner) 
    { 
     var obj = NHibernateUtil.String.NullSafeGet(rs, names[0]); 
     if (obj == null) return null; 
     var colorString = (string)obj; 
     return ColorTranslator.FromHtml(colorString); 
    } 

    public void NullSafeSet(IDbCommand cmd, object value, int index) 
    { 
     if (value == null) 
     { 
      ((IDataParameter)cmd.Parameters[index]).Value = DBNull.Value; 
     } 
     else 
     { 
      ((IDataParameter)cmd.Parameters[index]).Value = ColorTranslator.ToHtml((Color)value); 
     } 

    } 

    public object DeepCopy(object value) 
    { 
     return value; 
    } 

    public object Replace(object original, object target, object owner) 
    { 
     return original; 
    } 

    public object Assemble(object cached, object owner) 
    { 
     return cached; 
    } 

    public object Disassemble(object value) 
    { 
     return value; 
    } 

    public SqlType[] SqlTypes 
    { 
     get { return new[] {new SqlType(DbType.StringFixedLength)}; } 
    } 

    public Type ReturnedType 
    { 
     get { return typeof(Color); } 
    } 

    public bool IsMutable 
    { 
     get { return true; } 
    } 
} 

Le mapping suivant devrait alors travailler:

<property 
    name="Color" 
    column="hex_color" 
    type="YourNamespace.ColorUserType, YourAssembly" /> 

Pour être complet, et grâce à Josh pour cela, si vous utilisez FluentNHibernate, vous pouvez mapper comme ceci:

Map(m => m.Color).CustomTypeIs<ColorUserType>(); 
+0

Cela fonctionne vraiment bien. Je n'ai pas réalisé que je pouvais utiliser un type natif, et juste le mapper avec l'implémentation IUserType. Je pensais que je devrais utiliser l'implémentation IUserType comme type dans mon POCO aussi. Merci! –

+0

David, pouvez-vous mettre à jour votre réponse avec le commentaire "Un type d'utilisateur NHibernate ne remplace pas ce type ..." que vous avez posté ci-dessus? Et aussi mettre la cartographie qui fonctionnerait avec cela aussi. Je suis sûr qu'il y aura plus de gens comme moi qui ne réalisent pas que c'est le comportement. J'ai déjà utilisé IUserType, mais le type était complètement personnalisé. –

+0

A fait, mais la cartographie est de la mémoire - s'il vous plaît laissez-moi savoir si cela ne fonctionne pas! –

0

je le ferais comme ceci:

Je voudrais créer une propriété de chaîne privée ou d'un champ dans ma classe, et la carte de cette propriété/champ à la colonne que vous utilisez pour stocker la couleur dans votre base de données.

Ensuite, je créerais une propriété publique dans ma classe, qui retourne une couleur, et dans le getter de cette propriété, je convertir la chaîne qui est stockée dans le domaine privé/propriété à une couleur, et dans la setter, je définirais le champ/propriété string à la valeur qui correspond à la valeur de couleur qui a été donnée.

public class MyEntity 
{ 

    private string htmlColorString; 

    public Color TheColor 
    { 
     get { return System.Drawing.ColorTranslator.FromHtml (htmlColorString); } 
     set 
     { 
       htmlColorString = System.Drawing.ColorTranslator.ToHtml(value); 
     } 
    } 

} 
+0

Vous pouvez convertir un hex en RGB, puis utiliser la méthode Color.FromArgb(). –

+0

C'est en fait ce que je suis en train de faire. La méthode pour effectuer la conversion est System.Drawing.ColorTranslator.FromHtml (string "#ffffff") et System.Drawing.ColorTranslator.ToHtml (couleur myColor). Pouvez-vous confirmer qu'il n'y a pas de façon intégrée de faire une conversion de type? –

0

Je voudrais aller à l'approche de la mise en œuvre de Frederik et faire la conversion comme suit:

hex Convertir en RVB - chaque paire de valeurs hexagonales est l'une des composantes RVB - # 23FF00 signifie R = 23 , G = FF, B = 00.

Cela vous donnera la valeur int pour chacune des composantes RVB, une fois que vous faites une chaîne analyse syntaxique sur votre valeur hexadécimale:

int.Parse("FF", System.Globalization.NumberStyles.AllowHexSpecifier); 

Après cela, il suffit d'appeler Color.FromArgb() statique et vous Je vais avoir votre couleur.

+1

Il existe un convertisseur de couleur intégré: System.Drawing.ColorTranslator. –

2

Je prendrais les 15 minutes pour écrire une implémentation IUserType pour convertir directement vers/depuis la propriété de couleur afin que vous n'ayez pas de propriétés magiques.

Voir http://www.lostechies.com/blogs/rhouston/archive/2008/03/23/mapping-strings-to-booleans-using-nhibernate-s-iusertype.aspx

Cela a aussi l'avantage que vous pouvez utiliser votre propriété de couleur dans HQL ou Linq, que vous ne seriez pas en mesure de le faire avec des propriétés magiques, mais avec une couleur ce ne peut pas être un problème.