在NHibernate中使用GUID类型作为主键并保存实体

时间:2012-11-10 20:19:17

标签: nhibernate fluent-nhibernate

我使用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数据类型时,它正在正确保存。

我阅读了wont save to database with guid as id- fluent-nhiberate个问题,并使用Save()方法将GUIdD保存为成员实体作为键,但它不起作用!

感谢您的考虑。

2 个答案:

答案 0 :(得分:3)

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

有关刷新的更多信息: http://nhibernate.info/doc/nh/en/index.html#manipulatingdata-flushing

答案 1 :(得分: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交易一无所知。绊倒我的是Castle Windsor documentation

的这一部分
  

我们刚刚做了一件重要的,虽然看不见的效果。   通过注册组件,我们不仅告诉温莎如何   创造它们。温莎也将照顾好正确的摧毁   我们的实例,因此照顾管理他们的整个生命周期。在   外行人说,温莎会在没有的情况下处理这两件物品   更长时间的使用。这意味着它将刷新我们所做的更改   ISession为我们的数据库,它将清理   ISessionFactory。我们免费获得所有这些。

如果你问我,那会很误导。