2009-06-30 23 views
3

Ist es möglich, nur eine Art von Typkonvertierung vorzunehmen und direkt auf System.Drawing.Color zu mappen? Ich speichere die Farben als HTML/CSS-Werte. d.h. #ffffff. Ich möchte nicht einen benutzerdefinierten Typ erstellen müssen, der IUserType implementiert, das ist nur ein Wrapper für System.Drawing.Color.NHibernate Zuordnung zu System.Drawing.Color

+0

Warum möchten Sie keinen Benutzertyp dafür erstellen? Es macht genau das, was Sie versuchen zu tun ... –

+0

David - Der Grund ist, weil es bereits einen Typ, System.Drawing.Color, gibt, der verwendet werden kann. Warum diesen Typ neu erstellen? –

+2

Ein NHibernate-Benutzertyp ersetzt diesen Typ nicht. Er implementiert lediglich die Logik, um ein Datenbankfeld in diesen Typ zu übersetzen. Sie mappen mit dem Typ, Sie speichern eine Zeichenfolge in der Datenbank und Sie legen Ihre Eigenschaft als System.Drawing.Color offen. Will post code ... –

Antwort

6

Versuchen Sie dies für die Größe. Ein NHibernate-Benutzertyp ersetzt nicht den Typ, den Sie bereitstellen möchten. Er stellt lediglich den Mechanismus für die automatische Zuordnung vom gespeicherten Datenbanktyp zum .NET-Typ (hier von String zu Color und umgekehrt) bereit.

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; } 
    } 
} 

Die folgende Abbildung soll dann arbeiten:

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

Für Vollständigkeit und dank Josh dafür, wenn Sie FluentNHibernate verwenden, können Sie es wie diese Karte können:

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

Das funktioniert wirklich gut. Ich habe nicht erkannt, dass ich einen nativen Typ verwenden und es nur mit der IUserType-Implementierung zuordnen kann. Ich dachte, ich müsste die IUserType-Implementierung auch als Typ in meinem POCO verwenden. Vielen Dank! –

+0

David, kannst du deine Antwort mit dem "Ein NHibernate-Benutzertyp wird diesen Typ nicht ersetzen ...", den du oben gepostet hast, aktualisieren? Und auch das Mapping, das damit arbeiten würde. Ich bin mir sicher, dass es mehr Leute wie mich geben wird, die nicht erkennen, dass dies das Verhalten ist. Ich habe IUserType zuvor verwendet, aber der Typ war vollständig benutzerdefiniert. –

+0

Haben Sie getan, aber das Mapping ist aus dem Speicher - bitte lassen Sie mich wissen, wenn es nicht funktioniert! –

0

Ich würde es tun, wie folgt:

ich eine private String-Eigenschaft oder ein Feld in meiner Klasse schaffen würde, und ordnen Sie diese Eigenschaft/Feld die Spalte, die Sie die Farbe in der Datenbank zu speichern, verwenden.

Dann würde ich eine öffentliche Eigenschaft in meiner Klasse erstellen, die eine Farbe zurückgibt, und im Getter dieser Eigenschaft würde ich die Zeichenfolge, die in dem privaten Feld/Eigenschaft gespeichert ist, in eine Farbe und in der konvertieren Setter, ich würde das Stringfeld/die Eigenschaft auf den Wert setzen, der dem angegebenen Farbwert entspricht.

public class MyEntity 
{ 

    private string htmlColorString; 

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

} 
+0

Sie können Hex in RGB konvertieren und dann die Color.FromArgb() -Methode verwenden. –

+0

Das mache ich gerade. Die Methode zur Konvertierung ist System.Drawing.ColorTranslator.FromHtml (Zeichenfolge "#ffffff") und System.Drawing.ColorTranslator.ToHtml (Color myColor). Können Sie bestätigen, dass es keine integrierte Möglichkeit für eine Typkonvertierung gibt? –

0

Ich würde mit Frederiksimplementierungsansatz und machen die Umwandlung wie folgt:

Convert Hex RGB - jedes Paar von Hex-Werte ist eine der RGB-Komponenten - # 23FF00 bedeutet R = 23 , G = FF, B = 00.

Dies gibt Ihnen den int-Wert für jede der RGB-Komponenten, nachdem Sie einige Zeichenfolge auf dem Hex-Wert tun Parsen:

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

Danach, rufen Sie einfach Color.FromArgb() statisch und Sie‘ Ich habe deine Farbe.

+1

Es gibt einen integrierten Farbkonverter: System.Drawing.ColorTranslator. –

2

Ich würde die 15 Minuten dauern, um eine IUserType-Implementierung zu schreiben, um direkt in/aus der Farbeigenschaft zu konvertieren, so dass Sie keine magischen Eigenschaften herumliegen haben.

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

Dies auch den Vorteil hat, dass Sie Ihre Farbeigenschaft in HQL oder Linq verwenden können, die Sie nicht mit magischen Eigenschaften zu tun, wären in der Lage, wenn auch mit einer Farbe dies kein Problem sein.

Verwandte Themen