c# – Fluent NHibernate:我如何使用Int64作为ID?

我对ORM,NHibernate和FluentNH的整个概念都很陌生,我正在努力完成一些看起来如此简单的事情……

我正在尝试检索一个在其类中具有定义为Int64的字段的对象.该字段将是地图文件中定义的ID.

当尝试从数据库中检索记录时,NHibernate返回以下错误消息:“提供了错误类型的ID.预期: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重新定义我的对象ID时,一切正常!我需要使用更大的类型!

非常感谢!

编辑1:正如Aaronaught提到的那样,我同意,我对Int64的需求对于存储假期来说需要一些开销……但是有一秒钟,让我们忘记“假期”的概念.我将如何处理我的日志记录表(每秒5到10个事件(行)!).谢谢!

编辑2:@Paco:我正在使用NHibernate 2.1.2.4000和FluentNH 1.0.0.614

编辑3:在重新编写Daniel Schilling的解决方案后,重建了一个使用Int64作为ID的(全新的)简单Holiday对象.我能够成功地从数据库中检索记录.一旦我添加了一个与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>();
    }
}

公共HolidayGroupMap()
 {
  Id(x => x.HolidayGroupID);
  地图(x => x.Name);
  地图(x => x.Notes);
  地图(x => x.IsActive);
  HasMany(x => x.Holidays)
   .Cascade.All()
 }

最佳答案 我知道说它对我有用并不是很有帮助,但是……它对我有用.我使用Fluent NHibernate一直使用我的id.我的版本:

> NHibernate 2.1.0.4000
>流利的NHibernate 1.0.0.598

正如其他人所评论的那样,这可能是NHibernate或Fluent NHibernate的一个问题.要找出问题所在,使用ExportTo方法找出Fluent NHibernate生成的* .hbm.xml.请参阅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.hbm.xml文件中.如果您看到System.Int64,那么问题必须在NHibernate或您的代码中.如果问题出在NHibernate上 – 它必定是自2.1.0以来引入的问题(因为它对我有用).尝试使用我正在使用的相同版本.如果问题消失了,那就是新版本的NHibernate的错.

如果这不能解决问题,那么(不幸的是)问题很可能在于您自己的代码. Global.NHibernate_SessionFactory如何实例化?是否有可能使用一个Configuration对象导出模式而另一个实例正在创建SessionFactory?

这些都是我的想法.祝好运.

编辑1:
关于与HolidayGroup的关系(对不起 – 之前没有注意到):我认为你的意思是引用而不是HasOne – 见question 1622007.另外,你需要标记关系的一面Inverse() – 通常你会把它放在HasMany方面.

编辑2:
错误应用的HasOne肯定是此错误的来源.默认情况下,一对一关系映射为两个共享主键的表.子项的主键列通常与父键的主键具有外键关系.通过说“Holiday has-one HolidayGroup”,您将Holiday up设置为父级,将HolidayGroup设置为子级(这与您想要的相反).

当NHibernate尝试加载与HolidayGroup关联的Holiday时,它将使用HolidayGroup的Int32 ID并尝试检索具有相同ID的Holiday.但是,Holiday具有Int64 ID,因此出错.

在“编辑1”下进行更改,此问题应该消失.

>将HasOne更改为引用.
>将Inverse()添加到HolidayGroup的HasMany.

点赞