我对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() }
答案 0 :(得分:2)
我知道说它对我有用并不是很有帮助,但是......它对我有用。我使用Fluent NHibernate一直使用long
作为我的id。我的版本:
正如其他人所评论的那样,这可能是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”下进行更改,此问题应该消失。
HasOne
更改为References
。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);
}
}