2012-03-28 11 views
1

eine Klasse wie folgt vorstellen:Karte Flaggen Enum-Eigenschaft auf separaten Tabelle

public class MyEntity : Entity 
{ 
    public virtual States States { get; set; } 
} 

[Flags] 
public enum States 
{ 
    None, 
    State1 = 1, 
    State2 = 2, 
    State3 = 4, 
    State4 = 8 
} 

Ich möchte es auf diese Tabelle zur Karte:

TABLE MY_ENTITY 
ID: PK 
STATES_ID : FK to MY_ENTITY_STATES 

TABLE MY_ENTITY_STATES 
ID: PK 
IS_STATE1_SET (bit) 
IS_STATE2_SET (bit) 
IS_STATE3_SET (bit) 
IS_STATE4_SET (bit) 

ist das möglich?

Dies ist ein Legacy-Szenario, ich kann die Datenbank nicht ändern.


Wie pro Antrag, hier einige Daten Beispiel:

Tabelle MY_ENTITY

ID | STATES_ID 
---+---------- 
14 | 35 

Tabelle MY_ENTITY_STATES

ID | IS_STATE1_SET | IS_STATE2_SET | IS_STATE3_SET | IS_STATE4_SET 
---+---------------+---------------+---------------+-------------- 
35 | 0    | 1    | 0    | 1 

Diese auf einen Wert von States.State2 | States.State4 in der States führen sollte Eigentum in der MyEntity Instanz mit der ID 14.

Antwort

2

Dies ist eine zweistufige Lösung.

Verwenden Sie zuerst join, um den MY_ENTITY_STATES-Datensatz zu erstellen, und schreiben Sie dann IUserType, die die Flags in Spalten konvertiert.

Überprüfen Sie here für ein Beispiel.

+0

Danke, das sieht gut aus. Ich werde es morgen testen. Können Sie bitte eine Skizze des Mappings in Fluent NHibernate zur Verfügung stellen? –

+0

.Join (etwas ... Map (theproperty) .Type (thetype) ... so etwas :-) Ich benutze nicht fließend; Sie müssen es mit Intellisense herausfinden. –

+0

Ich bin nicht ganz sicher, wie man das macht. In der von Ihnen bereitgestellten Verknüpfung wird die Implementierung von ICompositeUserType als Mapping zwischen einer Klasse mit zwei Eigenschaften und zwei Spalten eingeführt. Aber ich habe nur ein enum ohne Eigenschaften. Was würde ich z. für 'PropertyTypes' oder' PropertyNames'? –

0

Ich habe eine einfache IUserType Implementierung erstellt, um das Mapping zu erreichen. Eine Implementierung eines ICompositeUserType ist nicht notwendig:

public class StatesUserType : IUserType 
{ 
    private static readonly SqlType[] _sqlTypes = { 
      NHibernateUtil.Int16.SqlType, NHibernateUtil.Int16.SqlType, 
      NHibernateUtil.Int16.SqlType, NHibernateUtil.Int16.SqlType }; 

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

    public SqlType[] SqlTypes 
    { 
     get { return _sqlTypes; } 
    } 

    public object NullSafeGet(IDataReader rs, string[] names, object owner) 
    { 
     var result = States.None; 
     if (((short)rs[names[0]]) == 1) 
      result |= States.State1; 
     if (((short)rs[names[1]]) == 1) 
      result |= States.State2; 
     if (((short)rs[names[2]]) == 1) 
      result |= States.State3; 
     if (((short)rs[names[3]]) == 1) 
      result |= States.State4; 

     return result; 
    } 

    public void NullSafeSet(IDbCommand cmd, object value, int index) 
    { 
     if (value == null) 
      return; 
     if (value.GetType() != typeof(States)) 
      return; 
     var states = (States)value; 
     cmd.Parameters[index] = states.HasFlag(States.State1); 
     cmd.Parameters[index] = states.HasFlag(States.State2); 
     cmd.Parameters[index] = states.HasFlag(States.State3); 
     cmd.Parameters[index] = states.HasFlag(States.State4); 
    } 

    public bool IsMutable 
    { 
     get { return false; } 
    } 

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

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

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

    public bool Equals(object x, object y) 
    { 
     return object.Equals(x, y); 
    } 

    public int GetHashCode(object x) 
    { 
     return x.GetHashCode(); 
    } 

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

Die Abbildung muss so etwas wie folgt aussehen:

Map(y => y.States).Columns.Add("IS_STATE1_SET", "IS_STATE2_SET", 
           "IS_STATE3_SET", "IS_STATE4_SET") 
        .CustomType<StatesUserType>(); 
Verwandte Themen