NHibernate更新无效

时间:2009-01-26 04:14:34

标签: c# asp.net-mvc nhibernate orm

我无法让我的更新工作。测试失败,我没有看到任何更新语句被发送到数据库。有人能告诉我我做错了吗?

这是我的存储库更新程序:

public void UpdateProject(Project proj)
{
    Session.Update(proj);
}

这是我正在尝试的单元测试:

[Test]
public void Can_Update_A_Project()
{
    var project = _projects[0];
    project.Name = "test project";

    repository.UpdateProject(project);

    var fromDb = repository.GetAProject(_projects[0].ID);
    Assert.AreEqual(project.Name, fromDb.Name);        
}

测试总是失败。我看到插入的测试数据,我看到测试的选择。我没有看到正在执行的更新。我错过了什么?

谢谢!

6 个答案:

答案 0 :(得分:20)

可能会发生一些事情。

1)更新失败,NHibernate引发了一个被某个地方吞噬的异常 - 这可能会发生,具体取决于你配置的方式。所以在VS中确保所有异常都会导致中断。

2)正在缓存更新而不是直接写入数据库 - 您可以使用Repository.Flush();

强制写入数据

3)你确定从数据库中读取了_projects [0] - 我假设在TestSetup中发生了这种情况吗?如果不是NHibernate将不会将其视为一个处于“控制”之下的对象。

顺便说一句 - 最好在测试中读取您要更改的数据,然后撤消该更改,将数据库重置为原始状态。这样,您的测试数据库将不会被您的测试更改。

BTW2 - 在上面的测试中,如果project.Name已经更新一次,即测试已经成功运行。然后,即使更新本身失败,下次测试也会成功。一种避免这种情况的方法 - 将DateTime附加到project.Name,不要将其设置为固定值。

答案 1 :(得分:6)

另一件事是:当您使用会话保存实体并使用实体的ID从同一会话加载相同的实体时,您将获得您保存的相同实例 - 无论是否有任何插入或更新发给数据库。

这是因为NHibernate的第一级缓存,它是属于会话的身份映射。

如果您希望测试检查实际写入数据库的内容,您可以这样做:

session.Save(someEntity);
session.Flush(); // forces the entity to be inserted
session.Clear(); // clears the session's identity map, thus
                 // detaching someEntity from the session

var loadedEntity = session.Get<EntityType>(someEntity.Id);

// now you may compare the fields of someEntity and loadedEntity
// to verify that they were actually persisted

答案 2 :(得分:5)

NHibernate中的

ISession.Update不会提交对数据库的更改。它用于更新与用于检索实例的会话不同的会话中的瞬态实例(有关详细信息,请参阅here)。刷新会话时,会将更改发送到数据库。默认情况下,会话以FlushOnCommit模式运行,这意味着在提交NHibernate事务时,对象的更改将被发送到数据库(有关不同刷新模式的详细信息,请参阅here)。

答案 3 :(得分:0)

尝试这可能是我错了,但它的作品


 public void UpdateProject(Project proj)
 {
    ISessionFactory SessionFactory;

    ISession session = SessionFactory.OpenSession();

    using (ITransaction transaction = session.BeginTransaction())
    {

      session.Update(proj);
      transaction.Commit();

    }
 }

答案 4 :(得分:0)

FlushMode <!/ H2>

我正在维护一个我没有写过的应用程序,并且发现即使您使用事务并调用txn.Commit(),如果您的NHibernate会话 {{{}仍然可能看不到更改1}}

很容易被发现。设置断点并查看session.FlushMode = FlushMode.Never。或者只搜索FlushMode的所有* .cs文件。

答案 5 :(得分:0)

我最近遇到了同样的问题。

  1. 插入工作
  2. 更新没有
  3. 这个问题是编码中的一个缺陷。检查数据是否更改了行,然后映射了新实体,并发送了更新,但没有任何反应。

    解决方案:必须从数据库中查询实际行,然后将C#中的更改应用于已撤回的该行。现在NHibernate知道行已更改,运行save并且一切正常。

      public void SaveChanges()
      {
          _session.Flush();
          _session.Transaction.Commit();
          _session.BeginTransaction();
      }