我使用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保存为成员实体作为键,但它不起作用!
感谢您的考虑。
答案 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。我们免费获得所有这些。
如果你问我,那会很误导。