Свободный NHibernate: Как я могу использовать Int64 в качестве идентификатора? - PullRequest
4 голосов
/ 27 января 2010

Я совершенно новичок во всей концепции ORM, NHibernate и FluentNH, и я пытаюсь сделать что-то, что кажется таким простым ...

Я пытаюсь получить объект, который имеет поле, определенное как Int64 в своем классе. Это поле будет идентификатором, как определено в файле карты.

При попытке извлечь запись из БД NHibernate возвращает следующее сообщение об ошибке: «Указан неверный тип. Ожидается: System.Int32, получен System.Int64»

У меня очень простой объект:

public class Holiday
{
    public virtual Int64 HolidayID { get; set; }
    public virtual string Name { get; set; }
    public virtual int Day { get; set; }
    public virtual int Month { get; set; }
    public virtual bool IsActive { get; set; }
    public virtual HolidayGroup Group { get; set; }

    public Holiday() { }

}

Файл сопоставления (для FluentNH) следующий:

public class HolidayMap : ClassMap<Holiday>
{
    public HolidayMap()
    {

        Id(x => x.HolidayID);
        Map(x => x.Name);
        Map(x => x.Day);
        Map(x => x.Month);
        Map(x => x.IsActive);
        HasOne(x => x.Group);
    }
}

структура таблицы (созданная NH) следующая:

CREATE TABLE [dbo].[Holiday](
 [HolidayID] [bigint] IDENTITY(1,1) NOT NULL,
 [Name] [nvarchar](255) NULL,
 [Day] [int] NULL,
 [Month] [int] NULL,
 [IsActive] [bit] NULL,
 [HolidayGroup_id] [int] NULL,
PRIMARY KEY CLUSTERED 
(
 [HolidayID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

и, наконец, я пытаюсь получить экземпляр Holiday, используя это:

    public static Holiday Get(Int64 _holidayID)
    {
        Holiday _holiday = new Holiday();

        try
        {
            using (var session = Global.NHibernate_SessionFactory.OpenSession())
            {
                _holiday = session.Get<Holiday>(_holidayID); // EXCEPTION OCCURS HERE
            }
        }
        catch (Exception _ex)
        {
            // TODO : Implement proper logging
        }

        return _holiday;
    }

Что я делаю не так ?? Чего не хватает? При удалении таблицы и переопределении моего объекта с использованием Int32 для идентификатора все работает! Мне нужно использовать больший тип!

Большое спасибо!

РЕДАКТИРОВАТЬ 1: Как Aaronaught упоминает, я согласен, моя потребность в Int64 немного накладных расходов для хранения праздников ... Но на секунду давайте забудем " Праздники »концепция. Что я собираюсь делать с моей таблицей журналов (от 5 до 10 событий (строк) в секунду!). Спасибо!

РЕДАКТИРОВАТЬ 2: @Paco: я использую NHibernate 2.1.2.4000 и FluentNH 1.0.0.614

РЕДАКТИРОВАТЬ 3: После переобработки решения Daniel Schilling перестроить (совершенно новый) простой объект Holiday, который использовал Int64 в качестве идентификатора. Мне удалось успешно извлечь запись из БД. Как только я добавил отношение к объекту Group, при создании экземпляра объекта Holiday я получил то же сообщение об ошибке, что и раньше ... Вот класс и отображение HolidayGroup, на случай, если вы можете сказать мне, что я сделал не так ...

public class HolidayGroup
{
    public virtual int HolidayGroupID { get; set;}
    public virtual string Name { get; set; }
    public virtual string Notes { get; set; }
    public virtual bool IsActive { get; set; }
    public virtual IList<Holiday> Holidays { get; set; }

    public HolidayGroup()
    {
        Holidays = new List<Holiday>();
    }
}

public HolidayGroupMap () { Id (x => x.HolidayGroupID); Карта (x => x.Name); Карта (x => x.Notes); Карта (x => x.IsActive); HasMany (x => x.Holidays) .Cascade.All () }

Ответы [ 2 ]

2 голосов
/ 27 января 2010

Я знаю, что не очень полезно просто говорить, что это работает для меня, но ... это работает для меня.Я использую long для своего идентификатора все время с Fluent NHibernate.Мои версии:

  • NHibernate 2.1.0.4000
  • Свободный NHibernate 1.0.0.598

Как прокомментировали другие, вполне возможно, что это может быть проблемой сNHibernate или Свободно NHibernate.Чтобы выяснить, в чем проблема, используйте метод ExportTo, чтобы узнать, что генерирует * .hbm.xml Fluent NHibernate.См. Раздел «Экспорт сопоставлений» на https://github.com/jagregory/fluent-nhibernate/wiki/Fluent-configuration.

Если FluentNHibernate работает правильно, вы должны увидеть что-то вроде ...

<id name="HolidayID" type="System.Int64, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
  <column name="HolidayID" />
  <generator class="identity" />
</id>

... в * .Holiday.hbmXML-файлЕсли вы видите, что System.Int64, то проблема должна быть в NHibernate или в вашем коде.Если проблема с NHibernate - это должна быть проблема, появившаяся начиная с 2.1.0 (поскольку она работает для меня).Попробуйте использовать ту же версию, которую я использую.Если проблема исчезнет, ​​то это будет новая версия ошибки NHibernate.

Если это не решит проблему, то (к сожалению) проблема, скорее всего, заключается в вашем собственном коде.Как создается Global.NHibernate_SessionFactory?Возможно ли, что один объект Configuration используется для экспорта схемы, а другой экземпляр создает SessionFactory?

. Это все мои идеи.Удачи.

РЕДАКТИРОВАТЬ 1: Относительно отношений с HolidayGroup (извините - раньше этого не замечали): я думаю, что вы имеете в виду References вместо HasOne - см. вопрос 1622007 .Кроме того, вам нужно отметить одну сторону отношения Inverse() - как правило, вы должны указать это на стороне HasMany.

РЕДАКТИРОВАТЬ 2: Неправильно примененное HasOne навернякаисточник этой ошибки.Отношения «один к одному» отображаются по умолчанию с двумя таблицами, которые имеют общие общие первичные ключи.Столбец первичного ключа дочернего элемента обычно имеет отношение внешнего ключа к первичному ключу родителя.Говоря «Holiday has-one HolidayGroup», вы устанавливаете Holiday как родительский, а HolidayGroup как дочерний (что противоположно тому, что вы хотели).

Когда NHibernate пытается загрузить Holiday, связанный сHolidayGroup, он возьмет IntG ID HolidayGroup и попытается получить Holiday, который имеет тот же ID.Однако у Holiday есть идентификатор Int64, что приводит к ошибке.

Внесите изменения в «РЕДАКТИРОВАТЬ 1», и эта проблема должна исчезнуть.

  1. Измените HasOne на References.
  2. Добавить Inverse() к HolidayGroup HasMany.
0 голосов
/ 27 января 2010

Вы пробовали это?

public class HolidayMap : ClassMap<Holiday>
{
    public HolidayMap()
    {

        Id(x => x.HolidayID).SetAttribute("type", "Int64");
        Map(x => x.Name);
        Map(x => x.Day);
        Map(x => x.Month);
        Map(x => x.IsActive);
        HasOne(x => x.Group);
    }
}
...