You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NHibernate中将Oracle序列映射至非ID列?

Oracle序列映射至非主键属性的问题解决

现有Oracle表结构

字段名数据类型
IDNUMBER
FOOVARCHAR2
BARNUMBER

对应的C#实体类

public class SomeClass
{
    public virtual long Id { get; set; }
    public virtual string Foo { get; set; }
    public virtual long Bar { get; set; }
}

问题描述

需将实体的Bar属性映射至Oracle序列ABC.Other_SEQ,但插入数据时Bar字段始终为NULL,其余数据可正常插入。

已尝试的无效方案

方案1:Formula配置(无效果无报错)

配置后插入时Bar仍为NULL,无任何报错信息:

public class SomeTableMapping
{
    Schema("ABC");
    Table("SomeTable");

    // ID序列生成器工作正常
    Id(p => p.Id, map =>
    {
        map.Column("ID");
        map.Generator(Generators.Sequence, 
          gMap => gMap.Params(new { sequence = "MyID_SEQ" }));
    });

    Property(p => p.Foo, map => map.Column("FOO"));

    // 此配置无效果,也不报错
    Property(p => p.Bar, map => map.Formula("SELECT ABC.Other_SEQ.nextval BAR FROM dual"));
}

注:Formula仅用于查询阶段计算字段值,不会影响插入语句的字段赋值。

方案2:添加Generated配置(实体有值但数据库无记录)

配置后实体实例的Bar会生成值,但数据库中对应记录的Bar字段仍为NULL:

Property(p => p.Bar, map =>
{
    map.Column("BAR");
    map.Formula("ABC.Other_SEQ.nextval");
    map.Generated(PropertyGeneration.Insert);
});

注:Formula无法触发数据库插入时的序列取值,仅在内存中生成值但未写入数据库。

可行的映射方案

方案1:利用数据库列默认值(推荐,Oracle 12c+支持)

步骤1:修改Oracle表结构,给BAR列设置序列默认值

ALTER TABLE ABC.SomeTable MODIFY BAR DEFAULT ABC.Other_SEQ.nextval;

步骤2:修改NHibernate映射配置

Property(p => p.Bar, map =>
{
    map.Column("BAR");
    // 指定该字段由数据库在插入时生成
    map.Generated(PropertyGeneration.Insert);
    // 可选:禁止更新该字段,避免后续更新覆盖序列值
    map.NotUpdate(true);
});

插入时数据库会自动用序列值填充BAR列,NHibernate会在插入完成后将数据库生成的值同步回实体实例。

方案2:NHibernate插入时直接指定序列取值(兼容旧版Oracle)

如果无法修改表结构,可通过配置让NHibernate在插入语句中直接调用序列:

Property(p => p.Bar, map =>
{
    map.Column("BAR");
    // 指定字段由数据库在插入时生成
    map.Generated(PropertyGeneration.Insert);
    // 设置插入时的SQL表达式,直接调用序列
    map.InsertSqlFormula("ABC.Other_SEQ.nextval");
});

此配置会让NHibernate生成的插入语句中,BAR字段取值为序列的nextval,插入后同步值到实体。


内容的提问来源于stack exchange,提问作者Crowcoder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 21:07:14