我对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.