NHibernate FluentMapping

NHibernate FluentMapping

我有以下流利的映射class。对象位置上的组件 (属性) 类型设置为空字符串的默认值且不可为空。插入时出现异常,说我需要指定类型(不可为空),它不应该使用指定的默认值吗?

public class LocationMapping : FluentNHibernate.Mapping.ClassMap<Cradle.DomainEntities.Location>
    {
        public LocationMapping()
        {
            Id(x => x.ID);
            Map(x => x.Barcode).CustomSqlType("varchar(30)").Unique().Not.Nullable();
            Map(x => x.Name).CustomSqlType("varchar(30)").Not.Nullable();
            Map(x => x.Site).CustomSqlType("varchar(30)").Not.Nullable().Default("");
            Map(x => x.ERPLocation).CustomSqlType("varchar(15)").Not.Nullable().Default("");
            Component<Cradle.DomainEntities.Status>(x => x.Status, c => { c.Map(x => x.Name, "Status").CustomSqlType("varchar(20)"); });
            Component<Cradle.DomainEntities.Type>(x => x.Type, c => { c.Map(x => x.Name, "Type").CustomSqlType("varchar(20)").Default("").Not.Nullable(); });
            Component<Cradle.DomainEntities.Category>(x => x.Category, c => { c.Map(x => x.Name, "Category").CustomSqlType("varchar(20)"); });
            Map(x => x.isActive).Not.Nullable().Default("1");
            Map(x => x.NonStock).Not.Nullable().Default("0");
        }
    }

Component<Cradle.DomainEntities.Type>(x => x.Type, c => { c.Map(x => x.Name, "Type").CustomSqlType("varchar(20)").Default("").Not.Nullable(); });

在映射中定义 Default 不会更改 .Net 默认值。

当你实例化你的 Location class 时,我猜你的 Type 属性 没有初始化(没有初始化值或构造函数没有设置它)因此有它的字符串的默认 .Net 值:null.

NHibernate 不会用您声明的 Default 替换 null。它怎么会猜到它不是自愿设置为空的?

您应该使用 class 定义中的默认值初始化 class 属性。

尽管如此,还是可以使用一种变通方法。对于 string 属性和其他可空属性,您可以在 class 上使用 dynamic-insert 选项,因为它会导致 NHibernate 不向 DB 发送空属性。

See the doc:

(8) dynamic-insert (optional, defaults to false): Specifies that INSERT SQL should be generated at runtime and contain only the columns whose values are not null.

当然,它不能处理具有不可空类型的属性。

那么,官方支持在映射中定义默认值的目的是什么?我只知道一个:启用从映射生成数据库模式以生成列的默认约束。

我们可以考虑 dynamic-insert 选项应该考虑这些默认值。但如果是这种情况(也许是这样,NHibernate 文档有时会落后于实现的功能),那将导致我建议的 'workaround' 失败,因为动态插入的行为应该是 仅包含其值等于它们在映射中声明的默认值的列,或者如果它们没有声明的默认值则为 null.