流畅的NHibernate:我如何使用Int64作为ID?

时间:2010-01-26 22:00:30

标签: c# nhibernate sql-server-2008 fluent-nhibernate

我对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 =&gt; x.HolidayGroupID);   地图(x =&gt; x.Name);   地图(x =&gt; x.Notes);   地图(x =&gt; x.IsActive);   HasMany(x =&gt; x.Holidays)    .Cascade.All()  }

2 个答案:

答案 0 :(得分:2)

我知道说它对我有用并不是很有帮助,但是......它对我有用。我使用Fluent NHibernate一直使用long作为我的id。我的版本:

  • NHibernate 2.1.0.4000
  • Fluent 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的关系(抱歉 - 之前没有注意到):我认为你的意思是References而不是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”下进行更改,此问题应该消失。

  1. HasOne更改为References
  2. Inverse()添加到HolidayGroup的{​​{1}}。

答案 1 :(得分:0)

你试过这个吗?

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