Fluent NHibernate возвращает IList ‹T› с NULL-записями

Хорошо, я сделал почти все, что мог придумать. Последние 2 дня я перебирал все выбранные поисковые системы и еще не нашел для этого решения.

ОБНОВЛЕНИЕ :: Я даже дошел до того, что сгладил классы, как показано ниже.

Вот что у меня есть ...

ПРИМЕЧАНИЕ: Имена классов и имена свойств изменены из-за конфиденциальности данных!

У меня есть объект сущности с именем «MyData». Похоже на это ...

public class MyData
{
    public virtual int id { get; set;}
    public virtual int StepId { get; set;}
    public virtual Decimal ProjectedValue { get; set;}
    public virtual String Stage { get; set;}
    public virtual String CreatedBy { get; set;}
    public virtual DateTime CreatedDate { get; set;}
    public virtual int RunId { get; set;}
    public virtual Int32 DataKey { get; set;}
    public virtual DateTime ForecastDate { get; set;}
    public virtual String UnitMeasure { get; set;}
    public virtual String FixedFlag { get; set;}
    public virtual String DataSource { get; set;}
    public virtual String ResourceType { get; set;}
    public virtual String DataType { get; set;}     

              public override bool Equals(object obj)
    {
        //Not implemented
        return false;
    }

    public override int GetHashCode()
    {            
        return base.GetHashCode();
    }

    public MyData()
    {
    }
     }

Вот код, который используется для карты.

        Table("MYDATA");
        CompositeId()
            .KeyProperty(mtm => mtm.RunId, "RUN_ID")
            .KeyProperty(mtm => mtm.DataKey, "CC_KEY")
            .KeyProperty(mtm => mtm.ForecastDate, "FORECAST_DATE")
            .KeyProperty(mtm => mtm.UnitMeasure, "UOM")
            .KeyProperty(mtm => mtm.FixedFlag, "FIXED_FLAG")
            .KeyProperty(mtm => mtm.DataSource, "DATA_SOURCE")
            .KeyProperty(mtm => mtm.ResourceType, "RESOURCE_TYPE")
            .KeyProperty(mtm => mtm.DataType, "DATA_TYPE")
        Map(mtm => mtm.StepId, "STEP_ID").Not.LazyLoad();
        Map(mtm => mtm.ProjectedValue, "PROJECTED_VALUE");
        Map(mtm => mtm.Stage, "STAGE").Not.LazyLoad();
        Map(audit => audit.CreatedBy, "CREATED_BY").Not.Nullable();
        Map(audit => audit.CreatedDate, "CREATED_DATE");

Этот класс отвечает требованиям для сопоставления NHibernate и Fluent. Мы конвертируем NHibernate в Fluent.

Когда я добавляю два ограничения к объекту ICriteria и вызываю метод для возврата данных, я получаю (в этом конкретном примере) более 15000 записей, но все они равны NULL. Нет ни свойств, ни ценностей, ничего. Однако количество возвращенных строк ОЧЕНЬ ТАКОЕ, как если бы я выполнял выборку в базе данных. Вот код, который я использую для выбора данных из приложения. Имейте в виду, что тот же самый код отлично работает для других объектов, поскольку мы фактически повторно используем этот метод!

        ICriteria c = _session.CreateCriteria(typeof(T));

        foreach (string searchField in searchCriteria.Keys)
        {
            c.Add(Restrictions.Eq(searchField, searchCriteria[searchField]));
        }

        IList<T> l = c.List<T>();

Когда я просматриваю код, коллекция «l» содержит строки, но все они являются объектами NULL. Однако они относятся к Типу.

Пара заключительных мыслей ...

  1. Другие объекты в базе кода используют тот же объект ICriteria и нормально возвращают данные.
  2. Отображение NHibernate этого объекта идентично сопоставлению Fluent.
  3. Это приложение, содержащее этот код, работает достаточно хорошо, особенно для большого количества потребляемых и создаваемых данных.
  4. У этой таблицы базы данных в Oracle НЕТ PK. (Я это не проектировал, просто унаследовал!)

ПОМОЩЬ!! Я полностью сбит с толку этим возвратом и не могу найти ничего плохого.


person JamminJimE    schedule 11.07.2014    source источник


Ответы (1)


Я наконец понял это после трех дней размышлений о том, что сделал что-то не так.

В основном проблема заключалась в отображении объекта CompositeId. Перечисленные выше объекты были отредактированы в попытке удалить объект CompositeId целиком. Вместо того, чтобы ID был простым INT, это был объект, содержащий 8 других свойств.

Итак, столбец CC_KEY (свойство DataKey) для указанного RunId был установлен в NULL в базе данных. Когда я пытался запросить объект и создать композитный ключ, нулевой объект вызывал сбой в КАЖДОЙ строке входящих данных. Это помешало FluentNHibernate создать объект CompositeId. Без идентификатора, без объекта! Это позволило системе вернуть мне правильное количество результатов, но при попытке создать каждый объект с нулевым значением CompositeKey.KeyColumn это не удалось.

Короче говоря, если вы создаете композитный идентификатор для сопоставленного объекта, УБЕДИТЕСЬ, что все ваши данные существуют и отсутствуют значения NULL!

person JamminJimE    schedule 14.07.2014