【问题标题】:NHibernate - deleting row is postponed to Commit(), but adding row not.NHibernate - 删除行被推迟到 Commit(),但不添加行。
【发布时间】:2018-07-31 12:43:19
【问题描述】:

我的问题是 NHibernate 推迟了删除行的操作,而其他操作没有推迟,它会导致异常。 在我的数据库中,我有带有唯一字段的用户表:登录。

我正在使用 NHibernate 5.1.3、.NET 版本 4.6.1、C#。 下面我粘贴导致问题的代码片段:

        var user1 = new UserEntity(0, "John1", "Smith1", "login1", "password2");
        var user2 = new UserEntity(0, "John2", "Smith2", "login1", "password2");
        using (var tx = _session.BeginTransaction())
        {
            //_session.FlushMode = FlushMode.Always; //this does not help 
            _userRepository.Add(user1);
            _userRepository.Delete(user1);
            //_session.Flush(); uncommenting this helps 
            _userRepository.Add(user2);
            Console.WriteLine(tx.IsActive.ToString());
            Console.WriteLine("_session.IsOpen.ToString() = " + _session.IsOpen.ToString());
            tx.Commit();
        }

user1 和 user2 都具有相同的登录值,但我在添加用户 2 之前删除了 user1。我在添加 user1 的行上放置了断点,我在 SQL Server Profiler 中看到,当调用 Add() 方法时会立即添加行,但是当我调用 Delete() 时,它会被推迟;调用 tx.Commit() 时,该行在 SQL 中被删除,并导致此类异常:

NHibernate.Exceptions.GenericADOException: 'could not insert: 
[WCFService.DAL.UserEntity][SQL: INSERT INTO [User] (FirstName, LastName, 
Login, Password) VALUES (?, ?, ?, ?); select SCOPE_IDENTITY()]'

方法 Add 和 Delete 是在通用存储库中实现的,下面我向您展示代码:

public class GenericRepository<T> : IRepository<T> where T : class
{
    private readonly ISession _session;
    (...)
    public void Add(T entity)
    {
        _session.Save(entity);
    }

    public void Delete(T entity)
    {
        _session.Delete(entity);
    }

我试图在 Google 中查找 NHibernate 为何会这样,但找不到解释。这是错误还是预期行为?

虽然我取消注释这一行会有所帮助:

    //_session.Flush(); unlocking this helps

但我认为应该更加一致:要么各种数据修改(添加、更新、删除)应该立即发生,要么在事务提交时发生。 难道我做错了什么?

【问题讨论】:

    标签: c# nhibernate


    【解决方案1】:

    查看文档9.6. Flush

    Session 总是按以下顺序执行 SQL 语句(在 Flush 期间)

    • SQL语句按以下顺序发出

    • 所有实体插入,以相同的顺序使用 ISession.Save() 保存相应的对象

    • 所有实体更新

    • 所有集合删除

    • 所有集合元素的删除、更新和插入

    • 所有集合插入

    • 所有实体删除,以相同的顺序使用 ISession.Delete() 删除相应的对象

    所以,我们能做的,就是调用 Delete 和 Flush,然后是 Insert/Save。

    如果我们混合使用,则使用上述过程......总是

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多