【问题标题】:Fluent NHibernate : How can i use Int64 as ID?Fluent NHibernate:我如何使用 Int64 作为 ID?
【发布时间】:2010-01-26 22:00:29
【问题描述】:

我对 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 的解决方案后,重建了一个(全新的)简单 Holiday 对象,该对象使用 Int64 作为 ID。我能够成功地从数据库中检索记录。一旦我向 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() }

【问题讨论】:

  • 虽然您的代码看起来不错,但我很确定您不需要大于 Int32 的类型来存储假期列表(实际上,Int16 可能绰绰有余)。
  • 看起来像 NHiberante 中的一个错误。你用的是哪个版本?
  • 您几乎可以将 Fluent NHibernate 排除在这个等式之外,因为它正在生成正确的模式。实际查询只是 NH​​ibernate,因此,正如 Paco 所说,NH 本身可能存在错误。

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


【解决方案1】:

我知道仅仅说它对我有用并没有什么帮助,但是……它对我有用。我一直使用 long 作为我的 ID 和 Fluent NHibernate。我的版本:

  • NHibernate 2.1.0.4000
  • 流畅的 NHibernate 1.0.0.598

正如其他人所评论的,这可能是 NHibernate 或 Fluent 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.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 设置为父级,将 HolidayGroup 设置为子级(这与您想要的相反)。

当 NHibernate 尝试加载与 HolidayGroup 关联的 Holiday 时,它将采用 HolidayGroup 的 Int32 ID 并尝试检索具有相同 ID 的 Holiday。但是,Holiday 有一个 Int64 ID,因此会出现错误。

在“EDIT 1”下进行更改,这个问题应该会消失。

  1. HasOne 更改为References
  2. Inverse() 添加到HolidayGroupHasMany

【讨论】:

    【解决方案2】:

    你试过了吗?

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

    【讨论】:

    • 显然 "SetAttribute" 在 FluentNH 1.0 版中被移除 (wiki.fluentnhibernate.org/Release_notes_1.0)
    • 尝试了以下没有运气: Id(x => x.HolidayID) .CustomType(typeof(Int64)); (相同的结果 =>“提供了错误类型的 id。预期:System.Int32,得到 System.Int64”)
    猜你喜欢
    • 1970-01-01
    • 2011-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多