RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 851458
Accepted
Monk
Monk
Asked:2020-07-07 20:15:48 +0000 UTC2020-07-07 20:15:48 +0000 UTC 2020-07-07 20:15:48 +0000 UTC

在 NHibernate 的 OnFlushDirty 事件中更改实体

  • 772

有一个“设置”实体存储数据的路径。有些实体使用设置来构建其数据路径。

我想在更改设置时验证其他实体的路径,并在必要时重新保存它们。我是如何尝试的:

  1. 重叠Interceptor并捕获事件OnFlushDirty,它允许您捕获所需属性的变化:

    var folderIndex = propertyNames.ToList().IndexOf(nameof(Folder));
    if (folderIndex > -1 && previousState != null)
    {
      var previous = previousState[folderIndex] as string;
      var current = currentState[folderIndex] as string;
      if (previous != current)
      {
        var someEntities = session.Query<ISomeEntity>().Where(m => m.Setting == this).ToList();
        foreach (var someEntit in someEntities)
        {
          someEntity.RefreshFolder();
        }
      }
    }
    

计算结果是,由于更改在会话内部(已经在事务提交中),因此将自动获取更改。没有帮助。如果someEntity.RefreshFolder();添加session.SaveOrUpdate(someEntity)之后,奇迹不会发生,实体也不会被保存。

  1. 在外部,设置调用包含在事务中:

    using (var tranc = session.OpenTransaction())
    {
      try
      {
        session.SaveOrUpdate(setting);
        tranc.Commit();
      }
      catch (System.Exception)
      {
        tranc.Rollback();
        throw;
      }
    }
    
  2. 如第 1 点所示,有SomeEntity一个指向 的链接Setting,如果我尝试进行单独的交易,那么它会转到 SO,因为 保存的设置成为保存实体所必需的,它将导致再次保存实体。

  3. 所有会话都启用了它session.FlushMode = FlushMode.Commit,以便会话中的随机更改(例如,稍后通过异常验证)不会尝试将其保存到数据库中。

一般来说,我希望设置中更改文件夹的操作是事务性的,因为如果不是,那么您可以在事务完成后简单地执行相同的操作,而无需将它们相互链接,但是不再可能了以保证数据的有效性。

c#
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Monk
    2020-07-22T10:14:08Z2020-07-22T10:14:08Z

    显然,在 call 之后tranc.Commit();,不再可能添加对象以进行提交。从这里我们跳舞。

    使用它的主要原因OnFlushDirty是实体中的更改跟踪器。也可以手动获取此信息:

      var impl = session.GetSessionImplementation();
      var key = impl.PersistenceContext.GetEntry(entity);
    
      if (key == null)
      {
        var name = impl.GuessEntityName(entity);
        var persister = impl.GetEntityPersister(name, entity);
        return new ChangeTrackerArgs(persister.GetPropertyValues(entity, EntityMode.Poco), null, persister.PropertyNames);
      }
    
      var current = key.Persister.GetPropertyValues(entity, EntityMode.Poco);
      return new ChangeTrackerArgs(current, key.LoadedState, key.Persister.PropertyNames);
    

    因此,每个session.SaveOrUpdate(entity)变成

      var state = GetChangeTrackerArgs(entity)
      entity.BeforeSave(state);
      session.SaveOrUpdate(entity);
    

    那些。任何实体的保存调用现在BeforeSave可以对任何其他实体进行类似的调用,并且适用于任何嵌套。


    InterceptorOnFlushDirty仍然需要它,因为 除了显式引起SaveOrUpdate的变化外,hiber 还捕捉到了隐含的变化。因此,有一个类似的调用,entity.BeforeSave(new ChangeTrackerArgs(currentState, previousState, propertyNames)); 这个调用将不再能够将实体添加到事务中,但如果它突然进入隐式保存,它仍然会在保存之前验证实体。


    除了上述之外,虽然这与问题无关。hibera 中的更改跟踪器在会话上工作,因此对于正常操作,它需要在特定会话中获取一个实体,然后对其进行更改。如果在一个会话中接收到一个实体并尝试在另一个会话中保存,则跟踪器将为空,即 上面所有的折磨都不是很有用。

    • 0

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5