【问题标题】:Nhibernate and Mysql. Insert child uniqie entity休眠和Mysql。插入子 uniqie 实体
【发布时间】:2014-02-25 11:38:41
【问题描述】:

我有相关的表格。
例如 - Worker (id, mame, idWorkerType, ...)WorkerType (id, code (unique key), ...)

然后我有相同的类,这是映射的。

然后,我有这样的生成对象列表

  • 工人1
    • Id1
    • 姓名1
    • WorkerType1
      • IdType1
      • 代码类型1
  • 工人2
    • Id2
    • 姓名2
    • WorkerType1
      • IdType1
      • 代码类型1

      ...

逻辑如下:

foreach (var Worker in Workers)
{
    var WorkerTypeFromDB = GetWorkerTypeByField("Code", Worker.WorkerType.Code).FirstOrDefault();
    if (WorkerTypeFromDB == null)
    {
        session.Insert(Worker.WorkerType);
    }
    else
    {
        session.Update(Worker.WorkerType);
    }

    var WorkerFromDB = GetWorkerByField("Code", Worker.Code).FirstOrDefault();
    if (WorkerFromDB == null)
    {
        session.Insert(Worker);
    }
    else
    {
        session.Update(Worker);
    }
}

所以,在第一次迭代中,我插入了 WorkerType1 和 Worker1。 在第二次迭代中,我更新了 WorkerType1(因为相同的唯一代码)并尝试插入 Worker2...但我不能!
我得到异常 - 对象引用了一个未保存的瞬态实例 - 在刷新之前保存瞬态实例或将属性的级联操作设置为使其自动保存的内容。

我知道,这是因为我没有插入 WorkerType,但我不需要它。我已经在 db 中有 WorkerType1。

有人解释一下如何解决这个问题?

【问题讨论】:

    标签: c# mysql nhibernate


    【解决方案1】:

    这是可能的,但我们必须修复(不)适当的引用处理。一旦我们知道该对象存在于数据库中(具有相同的“代码”),并且我们将其加载到session 中,我们应该使用该对象引用

    所以变化应该是这样的:

    var WorkerTypeFromDB = GetWorkerTypeByField("Code", Worker.WorkerType.Code).FirstOrDefault();
    if (WorkerTypeFromDB == null)
    {
        session.Save(Worker.WorkerType); // Save/Insert not existing
    }
    else
    {
        Worker.WorkerType = WorkerTypeFromDB // assign the existing to our object
    }
    

    所以现在,一旦我们有了现有对象,我们就将其分配为属性WorkerType

    为了处理 Worker,我们可以做更多:Merge(),以防 Worker 已经存在。

    var WorkerFromDB = GetWorkerByField("Code", Worker.Code).FirstOrDefault();
    if (WorkerFromDB == null)
    {
        session.Save(Worker); // insert not existing
    }
    else
    {
        // here, we should assign the existing Worker ID to passed one
        Worker.ID = WorkerFromDB.ID; // current worker has same identifier
        session.Merge(Worker);       // both will be merged, latest changes will be applied      
    }
    

    最后,当调用session.Flush() 时,所有更改都将被持久化。 (Merge 甚至可以根据需要用于 WorkerType...)*

    阅读更多关于Merge()这里9.4.2. Updating detached objects,摘录:

    ...使用Merge(Object o)此方法将给定对象的状态复制到具有相同标识符的持久对象上。如果当前没有与会话关联的持久实例,它将被加载。该方法返回持久实例。如果给定的实例未保存或在数据库中不存在,NHibernate 将保存它并将其作为新的持久实例返回。否则,给定实例不会与会话关联。 在大多数具有分离对象的应用程序中,您需要 SaveOrUpdate() 和 Merge() 这两种方法

    【讨论】:

    • 如果有帮助就太好了 ;) 享受 NHibernate。
    猜你喜欢
    • 2017-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-04
    • 2013-07-24
    • 1970-01-01
    • 2011-12-05
    • 1970-01-01
    相关资源
    最近更新 更多