Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Nhibernate在保存或更新之前加载覆盖值_C#_Nhibernate - Fatal编程技术网

C# Nhibernate在保存或更新之前加载覆盖值

C# Nhibernate在保存或更新之前加载覆盖值,c#,nhibernate,C#,Nhibernate,我当前在运行更新函数时遇到问题,该函数首先使用session.Load()加载实体,然后使用session.SaveorUpdate() 我的问题是,如果我不先加载会话,nhibernate将不知道这些关系,因此尝试插入已经存在的数据,当我首先加载实体时,更新的实体将被数据库中已经存在的数据覆盖 public void Update(T Entity, bool load) { using(ISession session = this.helper.GetSession())

我当前在运行更新函数时遇到问题,该函数首先使用
session.Load()
加载实体,然后使用
session.SaveorUpdate()

我的问题是,如果我不先加载会话,nhibernate将不知道这些关系,因此尝试插入已经存在的数据,当我首先加载实体时,更新的实体将被数据库中已经存在的数据覆盖

public void Update(T Entity, bool load)
{
    using(ISession session = this.helper.GetSession())
    {
        using(ITransaction transaction = session.BeginTransaction())
        {
            if(load)
            {
                session.Load(Entity, Entity.ID);
            }

            session.SaveOrUpdate(Entity);
            transaction.Commit();
            session.Flush(); 
        }
    }
}
简言之:

  • 加载对象,然后将其与新值绑定(更改将在
    session.Flush()
    上保留,无需任何显式
    Update()
    调用)或
  • 使用有界值(包括ID)创建新的C#实例,并调用
    session.Update(myInstance)
更复杂的答案可以在doc的一个章节中找到:

许多应用程序需要在一个事务中检索对象,将其发送到UI层进行操作,然后在新事务中保存更改。(在高并发环境中使用这种方法的应用程序通常使用版本化数据来确保事务隔离。)这种方法需要与上一节描述的编程模型稍有不同的编程模型。NHibernate通过提供方法ISession.Update()来支持此模型

//在第一个会话中
Cat=第一次会话加载(catId);
Cat potentialMate=新Cat();
第一阶段。保存(潜在伴侣);
//在应用程序的更高层中
类别配偶=潜在配偶;
//稍后,在新的会话中
第二次会话。更新(cat);//更新cat
第二次会议。更新(配偶);//更新配偶
SaveOrUpdate()
的用法和语义似乎让新用户感到困惑。首先,只要您不试图在另一个新会话中使用来自一个会话的实例,就不需要使用
Update()
SaveOrUpdate()
。一些完整的应用程序永远不会使用这两种方法中的任何一种

通常在以下场景中使用
Update()
SaveOrUpdate()

  • 应用程序在第一个会话中加载对象
  • 对象被传递到UI层
  • 对该对象进行了一些修改
  • 对象被传递回业务逻辑层
  • 应用程序通过在第二个会话中调用Update()来持久化这些修改
因此,我们可以在一个会话中获得某个实体的实例。。。并关闭该会话。这样的对象甚至可以是全新的C#实例——其所有属性都由某个上层绑定(例如MVC绑定器或Web API格式化程序)

稍后,我们可以使用该实例并调用session.Update(myInstance)。NHibernate将获取该实体的ID并发出适当的update语句

另一种方法是调用Merge:

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


请阅读

欢迎您自己添加正确语言的标签。@Frankie_C抱歉,我肯定我写了C#谢谢Radim,这是一个非常有洞察力和有用的答案。在你以上建议的帮助下,我能够使我的方法发挥作用,现在对nhibernate有了更多的了解。这是非常好的信息。享受强大的NHibernate;)
// in the first session
Cat cat = firstSession.Load<Cat>(catId);
Cat potentialMate = new Cat();
firstSession.Save(potentialMate);

// in a higher tier of the application
cat.Mate = potentialMate;

// later, in a new session
secondSession.Update(cat);  // update cat
secondSession.Update(mate); // update mate