如何使用 nhibernate 更新主键

Posted

技术标签:

【中文标题】如何使用 nhibernate 更新主键【英文标题】:How do I update the primary key using nhibernate 【发布时间】:2011-08-29 18:21:29 【问题描述】:

我的一张表的主键是一个字符串。该字符串是我想在某个时间点更新的代码。我怎么能在休眠中做到这一点。 请注意,有一个外键连接到此列,我需要级联更新。

为了便于讨论,让我们假设我的映射如下

public class Code

    public virtual string Id  get; set; 
    public virtual string Name  get; set; 

    public class CodeMap : ClassMap<Code>
    
        public CodeMap()
        
            Table("BusinessCode");
            Id(x => x.Id, "Id");
            Map(x => x.Name, "Name").Nullable();
        

    
    

public class Data

    public virtual int Key  get; set; 
    public virtual Code DataCode get; set; 
    public virtual string Desc  get; set; 
    public class DataMap : ClassMap<Data>
    
        public DataMap()
        
            Table("Data");
            Id(x=>x.Key,"Key");
            Map(x => x.Desc).Column("desc");
            References(x => x.Code, "BusinessCode").Nullable().Cascade.SaveUpdate();
        
    

表结构

BusinessCode Table
Id(nvarchar(100)) -primarykey
Name(nvarchar(1024))



Data Table
id(int) - auto generated primary key
businesscode(nvarchar(100)) - foreign key to BusinessCode Id
desc(nvarchar(1024))

这是我用来更新对象的代码

using (var trans = Session.BeginTransaction())
            
                var modifiedSource = Session.Load<Code>(id);
                modifiedSource.Id = "newId";
                modifiedSource.Name = "new name";
                Session.Update(modifiedSource);
                trans.Commit();
            

【问题讨论】:

如果我是你,我只会创建一个新对象。 动态更改主键值可能是个坏主意。这更像是我书中的一次性手动脚本更新。 我第二个 dotjoe 和 @UpTheCreek:改变一个对象的 identity 意味着它不再是同一个对象。因此 - 创建一个新对象是有意义的。 我屈服于糟糕的设计...暂时不允许更新主键。 NHibernate - updating Identity fields的可能重复 【参考方案1】:

尝试“分配”id generator:

<class name="Dataset" table="Dataset" >
    <id name="id" column="id" type="String">
        <generator class="assigned" />
    </id>
    ...
</class>

或者

Id(x => x.Id).GeneratedBy.Assigned();

来自 NHibernate doc

5.1.4.7。分配的标识符

如果您希望应用程序分配标识符(而不是 让 NHibernate 生成它们),您可以使用分配的生成器。 这个特殊的生成器将使用已经分配的标识符值 到对象的标识符属性。使用这个时要非常小心 分配具有业务意义的键的功能(几乎总是一个可怕的 设计决策)。

由于其固有性质,使用此生成器的实体不能 通过 ISession 的 SaveOrUpdate() 方法保存。相反,你必须 明确指定到 NHibernate 是否应该保存对象或 通过调用 Save() 或 Update() 方法更新 会话。

【讨论】:

试过了(我从 DB 加载对象..更新两个字段并使用更新)..抛出错误说... 实例的标识符从 x 更改为 y跨度> @Mulki:你必须更具体,这是从哪里抛出的,堆栈跟踪等。看看这个:***.com/questions/2624109/… 添加了一些代码以提供有关其更新方式的更多详细信息.. iv 已经看到该问题..我直接更新对象...而不是通过另一个对象更新它 @Mulki:您发布的代码应该与“已分配”一起使用。请显示完整的堆栈跟踪。 如果它有效,我会感到惊讶。这意味着 NH 需要记住加载对象时的主键,因此它可以发出更新,如 update t set id = 4 where id = 3

以上是关于如何使用 nhibernate 更新主键的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 NHibernate 模式生成更新数据库表模式?

如何使用 Fluent nhibernate 正确更新行?

Nhibernate中的多个主键?

如何更新 Nhibernate 中的 varchar 列长度?

NHibernate 和字符串主键

使用 Fluent NHibernate 和 AsList() 时指定主键