2

我使用 NH 作为我的数据访问层,并且似乎 GUID 类型作为主键存在问题:

public partial class Member
    {
        public virtual Guid UserId { get; set; }
        public virtual string UserName { get; set; }
    }

 public MemberMapping()
        {
            Id(x => x.UserId).GeneratedBy.GuidComb();
            Map(x => x.UserName).Length(20).Not.Nullable();
        }

看起来,即使我将 UserId 更改为以下映射:

Id(x => x.UserId).GeneratedBy.Assgined();

然后初始化我自己的UserId,成员类型的对象没有开始保存......

但是当我为 UserId 使用 Int 数据类型时,它被正确保存。

我阅读了不会以 guid 作为 id-fluent-nhiberate问题保存到数据库并使用 Save() 方法以 GUIdD 作为键保存成员实体,但它不起作用!

感谢您的考虑。

4

2 回答 2

3

您在后续评论中链接到的页面是关于创建和注入会话的。它根本没有提到“事务”或“提交”。您应该始终使用 NHibernate 事务。在默认设置下,提交事务将触发会话以刷新对数据库的任何更改。这是一个必要的步骤,因为刷新是保证将更改发送到数据库的唯一步骤。

更多关于冲洗: http: //nhibernate.info/doc/nh/en/index.html#manipulatingdata-flushing

于 2012-11-11T13:24:50.660 回答
1

这实际上是我的一个重大疏忽。因为我的实体都使用原生 ID 生成,所以即使我从未刷新事务,它们也会在保存时插入。(规则的一个例外。请参阅这个出色的解释:https ://stackoverflow.com/a/43567/1015595 )

另一方面,您的成员实体将 ID 映射到 Guid。在这种情况下,对象的行为与预期一样,并且在事务被刷新之前不会持久化。

就像奥斯卡在他的回答中所说的那样,您应该在尝试保存任何内容并在之后提交交易之前开始交易。一个好的做法是将保存包装在 try-catch 语句中:

// Adds sample data to our database
public ActionResult Seed()
{
    ...

    StoreRepository.BeginTransaction();

    try
    {
        StoreRepository.SaveOrUpdateAll( barginBasin, superMart );

        StoreRepository.Commit();

        return RedirectToAction( "Index" );
    }
    catch
    {
        StoreRepository.Rollback();

        return RedirectToAction( "Error" );
    }
}

以下是您需要添加到存储库的方法:

public void BeginTransaction()
{
    Session.BeginTransaction();
}

public void Commit()
{
    Session.Transaction.Commit();
}

public void Rollback()
{
    Session.Transaction.Rollback();
}

您希望将这些方法保留在存储库中,以便您的控制器保持可测试性。

当我写那篇文章时,我对 NH 交易一无所知。让我绊倒的是温莎城堡文档的这一部分:

我们刚刚所做的事情有一个重要的,尽管是无形的影响。通过注册组件,我们不只是告诉 Windsor 如何创建它们。Windsor 还将为我们妥善销毁这些实例,从而管理它们的整个生命周期。用外行的话来说,温莎将在不再使用这两个对象时将它们处理掉。这意味着它将为我们将我们对 ISession 所做的更改刷新到数据库中,并清理 ISessionFactory。我们免费获得所有这些。

如果你问我,这很误导。

于 2012-11-28T20:24:18.243 回答