Сопоставить свойство перечисления flags с отдельной таблицей - PullRequest
1 голос
/ 28 марта 2012

Представьте себе такой класс:

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

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

Я хочу сопоставить это с этой таблицей:

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)

Возможно ли это?

Это устаревший сценарий, я не могу изменить базу данных.


В соответствии с запросом, вот некоторые примеры данных:

Таблица MY_ENTITY

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

Таблица MY_ENTITY_STATES

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

Это должно привести к значению States.State2 | States.State4 в свойстве States в экземпляре MyEntity с идентификатором 14.

Ответы [ 2 ]

2 голосов
/ 28 марта 2012

Это двухшаговое решение.

Сначала используйте join , чтобы получить запись MY_ENTITY_STATES, а затем напишите IUserType, который преобразует флаги в столбцы.

Проверьте здесь для примера.

0 голосов
/ 29 марта 2012

Я создал простую IUserType реализацию для достижения соответствия. Реализация ICompositeUserType не обязательна:

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

Отображение должно выглядеть примерно так:

Map(y => y.States).Columns.Add("IS_STATE1_SET", "IS_STATE2_SET",
                               "IS_STATE3_SET", "IS_STATE4_SET")
                  .CustomType<StatesUserType>();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...