Как загрузить объект из базы данных, где составной идентификатор записи содержит свойство ключа с нулевым значением? - PullRequest
0 голосов
/ 18 июля 2011

Я читаю данные из внешней организации, использующей Oracle.DataAccess через поставщика Oracle10g. В одной из таблиц есть составной идентификатор, состоящий из этих полей.

course:
  institutioncode: "X11"
  coursecode:      "N100"
  campuscode:      "A"
  entryyear:       2011
  entrymonth:      10

Проблема заключается в том, что внешнему провайдеру разрешено иметь код кампуса, а не пустой. Это приводит к тому, что nHibernate возвращает коллекции, содержащие нулевые ссылки вместо сущностей курса.

Другие доменные объекты также будут использовать эти поля для ссылки на эту сущность курса, так что это фактически используется в качестве ключа, и я не могу легко переназначить использование суррогатного ключа.

Из источника в теге 3.1.0GA, проверка, вызывающая такое поведение, может быть найдена в Nhibernate.Type.ComponentType.Hydrate(IDataReader rs, string[] names, ISessionImplementor session, object owner). Это всегда отвергает возможность того, что свойство ключа может быть нулевым. Может ли это изменение сделать обнуляемость опцией для свойств ключа и ссылки на ключ?

В противном случае, как бы вы порекомендовали читать эти данные напрямую с помощью nHibernate?

Ответы [ 2 ]

2 голосов
/ 19 июля 2011

NULL-значения в свойствах не поддерживаются по проекту .

Есть два способа справиться с этим:

  • Импортируйте данные вместо использования их в необработанном виде из источника, добавив правильный суррогатный ключ.
  • Обрабатывать эту сущность без NHibernate.
1 голос
/ 19 июля 2011

хорошо, мой первый комментарий не сработал для ссылок (ManyToOne). Итак, вот мое альтернативное решение: пользовательский тип для обхода чека.

class CourseMap : ClassMap<Course>
{
    public CourseMap()
    {
        CompositeId()
            .KeyProperty(c => c.InstitutionCode)
            .KeyProperty(c => c.CourseCode)
            .KeyProperty(c => c.CampusCode, key => key.Type(typeof(MyUserType)))
            .KeyProperty(c => c.EntryYear)
            .KeyProperty(c => c.EntryMonth);
    }
}

class MyUserType : IUserType
{
    public object Assemble(object cached, object owner)
    {
        return DeepCopy(cached);
    }

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

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

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

    public int GetHashCode(object x)
    {
        return (x == null) ? 0 : x.GetHashCode();
    }

    public bool IsMutable
    {
        get { return false; }
    }

    public object NullSafeGet(IDataReader rs, string[] names, object owner)
    {
        var value = NHibernateUtil.String.NullSafeGet(rs, names[0]);
        return (value == null) ? string.Empty : value;
    }

    public void NullSafeSet(IDbCommand cmd, object value, int index)
    {
        string d = string.IsNullOrEmpty((string)value) ? null : (string)value;
        NHibernateUtil.String.NullSafeSet(cmd, d, index);
    }

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

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

    public SqlType[] SqlTypes
    {
        get { return new[] { SqlTypeFactory.GetString(100) }; }
    }
}



class SomeEntityMap : ClassMap<SomeEntity>
{
    public EntityMap()
    {
        Id(e => e.Id).GeneratedBy.Assigned();

        References(e => e.Course)
            .Columns("InstitutionCode", "CourseCode", "CampusCode", "EntryYear", "EntryMonth")
            .Fetch.Join();  // important because we can't rely on values, NULL is invalid value
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...