【问题标题】:How do I update the primary key using nhibernate如何使用 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 意味着它不再是同一个对象。因此 - 创建一个新对象是有意义的。
  • 我屈服于糟糕的设计...暂时不允许更新主键。

标签: .net nhibernate orm fluent-nhibernate


【解决方案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:你必须更具体,这是从哪里抛出的,堆栈跟踪等。看看这个:stackoverflow.com/questions/2624109/…
  • 添加了一些代码以提供有关其更新方式的更多详细信息.. iv 已经看到该问题..我直接更新对象...而不是通过另一个对象更新它
  • @Mulki:您发布的代码应该与“已分配”一起使用。请显示完整的堆栈跟踪。
  • 如果它有效,我会感到惊讶。这意味着 NH 需要记住加载对象时的主键,因此它可以发出更新,如 update t set id = 4 where id = 3
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多