【问题标题】:Nhibernate : Updating a child entity directly without inverseNhibernate : 直接更新子实体而不反向
【发布时间】:2012-08-05 10:18:59
【问题描述】:

我正在使用 fluent nhibernate 将父子关系映射到 sql 数据库。
大多数时候我让父实体保存它的子实体,它们被插入到 1 个事务中,如果我没记错的话,如果我使用 .Inverse() 和 sql 标识列,这是不可能的。

我遇到的问题是,在一种特定情况下,我想更新子实体并且只更新子实体。
当我使用当前设置执行此操作时,子记录将失去与其父对象的关系(如果父对象为空)或将完全替换我的父对象(如果我插入一个只有 id 的虚拟父对象)。

有人知道在不影响外键的情况下实现单条记录更新的方法吗?
我可以想到手动 sql 语句或存储过程,但我希望有一种休眠方式。

我有以下设置(为方便起见进行了简化):

public ProjectMap()
{
  Table("Project");
  Id(p=> p.Id);
  HasMany(p => p.Risks).Not.LazyLoad();
}

public RiskMap()
{
  Table("ProjectRisk");
  Id(r=> r.Id);
  References(r => r.Project).Column("ProjectId");
  Map(r => r.Description);
}

public class Project
{
  public virtual int Id { get; set; }
  public virtual IList<Risk> Risks { get; set; }
}

public class Risk
{
  public virtual int Id { get; set; }
  public virtual string Description{ get; set; }
  public virtual Project Project { get; set; }
}

【问题讨论】:

  • 你想做什么?你可以发布有问题的代码吗?更新从数据库加载的现有风险时,如果您不手动设置,项目属性应保持不变。
  • 因为我在两者之间使用了肥皂服务(这是一个硬性要求),所以我没有序列化 Project 属性。如果我这样做了,那么所有子项都会有它的父项,并且我会有一个无限循环的序列化它们(更不用说传输的数据了)。即使引用对象在那里,如果进行了任何其他更改,它仍然会得到更新。
  • 澄清我在做什么:mvc网站通过soap服务加载一个项目。在客户端单击时,它会将 1 个风险对象发送回网络服务器以保存在数据库中。
  • 那么也许你应该从数据库加载风险,使用它的 ID,使用发送的实例更新它的属性并保存它。或者如果性能很关键,请进行 HQL 更新:nhforge.org/doc/nh/en/index.html#batch-direct
  • 我通常做的是在映射 DTO(在我的情况下为视图模型)时,我首先从存储库中按 ID 加载实体,然后将所有其他属性从 DTO 映射到域实体 - 使用 AutoMapper。

标签: c# .net nhibernate fluent-nhibernate


【解决方案1】:

正如 Miroslav 建议的那样,我现在正在使用 HQL 更新语句。

这对我的口味来说有点乱,但它可以完成工作。

Session.CreateQuery("update Risk set Closed = :completed where Id = :id")
                    .SetInt32("id", id)
                    .SetBoolean("completed", completed)
                    .ExecuteUpdate();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多