当有一个可以为空的数据库字段,开发人员忘记在相应的. Net实体中声明它可以为空时,我遇到了错误的NHibernateMap问题。
表格:
CREATE TABLE myTable
(
ID int NOT NULL,
Total int NOT NULL,
Discount int NULL --Nullable field
)
INSERT INTO myTable VALUES (1, 10, NULL)
C#实体:
public class MyTable{
public int ID { get; set; }
public int Total { get; set; }
public int Discount { get; set; } //not declared as nullable by mistake
}
NHibernateMap:
public class MyTableMap : ClassMap<MyTable>
{
public MyTableMap()
{
Table("dbo.myTable");
Id(x => x.ID).GeneratedBy.Assigned().Column("ID");
Map(x => x.Total).Column("Total");
Map(x => x.Discount).Column("Discount"); //setting mapping to .Nullable() doesn't change the behaviour
}
}
当我尝试加载实体时:
session.Get<MyTable>(1);
我本以为会得到一个异常,因为Discount字段为空,但NHibernate却以默认值0静默加载实体,然后在第一次会话时更新数据库表。Flush(),即使我没有更改实体的任何其他值。对于datetime字段,情况更糟,因为. Net DateTime的默认值是'01/01/0001',而我得到了异常:
The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value
其他人也遇到过同样的问题吗?SessionFactory中有没有配置强制NHibernate在NULL列Map到非空. Net属性时抛出异常?通过检查每个属性和列的每个Map很难解决这个问题,特别是当你在处理别人的代码时。
1条答案
按热度按时间emeijp431#
按照注解中的建议,我为基元类型编写了一些约定,当数据库值为NULL且属性未声明为可空时,基元类型会在NullSafeGet方法上抛出异常。
例如,以下是应用于Int属性的自定义类型:
公约:
最后在SessionFactory中添加约定:
您可以对所有其他基元类型(如DateTime、bool、double等)执行相同的操作。只需创建一个新的类型和约定,从正确的类型继承。
日期时间示例: