不要误解我的意思,我希望他们得到保存。但我一直以为我必须致电Session.SaveOrUpdate(x);
去做。但这是正在发生的事情。
尽管我从未调用过保存方法,但对象仍然被“保存”。
对象通过Fluent nHibernate
映射,这里没什么特别的。
我将ISessionFactory
和ISession
映射到Ninject
ASP.NET MVC
,就像这样。
Bind<ISessionFactory>()
.ToMethod(c => CreateSessionFactory())
.InSingletonScope();
Bind<ISession>()
.ToMethod(c => OpenSession())
.InRequestScope()
.OnActivation(session =>
{
System.Diagnostics.Debug.WriteLine("Creating Session");
session.BeginTransaction();
session.FlushMode = FlushMode.Commit;
})
.OnDeactivation(session =>
{
if (session.Transaction.IsActive)
{
try
{
System.Diagnostics.Debug.WriteLine("Disposing Session");
session.Transaction.Commit();
}
catch
{
session.Transaction.Rollback();
}
}
});
然后,当我想要执行某些操作时,我在域类上有一个简单的方法,或者扩展方法(只是因为它更容易组织),就像这样。
class Member {
public virtual int Id { get; set; }
public virtual string Email { get; set; }
public virtual string Password { get; set; }
}
然后,我在一些延伸方法中加入风味..
using System;
using System.Linq;
namespace System.Linq
{
public static class MembershipExtensions
{
public static void ChangePassword(this Membership.Member member, string password)
{
member.Password = System.Security.Cryptography.Hashing.ComputeHash(password, "SHA512", null);
}
public static bool VerifyPassword(this Membership.Member member, string password)
{
return System.Security.Cryptography.Hashing.VerifyHash(password, "SHA512", member.Password);
}
}
}
到目前为止,在Ooo的土地上一切都很好。现在这里的东西变得很糟糕。
[HttpPost]
public ActionResult Password(ViewModels.MemberEditPasswordViewModel model)
{
if (ModelState.IsValid)
{
// attempt to perform the password change on the current member.
var member = User.AsMember(); // retrieve the current user
if (member.VerifyPassword(model.Current)) // verify the current password
member.ChangePassword(model.Password);
//if (Bus.Update(member) != null) {
// return RedirectToAction("Index", "Home");
//}
//else {
// ModelState.AddModelError("", "The original password is incorrect.");
//}
}
// If we got this far, something failed, redisplay the form
// with the errors listed and give them a chance to try again.
return View(model);
}
这是疯狂的部分。 此作品。注意什么是这么奇怪?我从不对SaveOrUpdate
对象调用任何Member
种类。我评论了我的Update
代码只是为了测试它。
这是可能与问题相关的信息,但我不想用额外的代码来阻止所有事情。
对于那些寻找我的AsMember()
方法的人来说,这里也是如此。我想尽我所能提供所有数据。我喜欢这种行为,但我不确定这是正常还是正确......
using System;
using System.Linq;
using System.Linq.Expressions;
namespace System.Web.Mvc
{
public static class MembershipProviderExtensions
{
public static Membership.Member AsMember(this System.Security.Principal.IPrincipal user)
{
// if the user is not authenticated, then we should
// not have made it this far, and error out gracefully.
if (!user.Identity.IsAuthenticated)
return null;
// get the service bus from the locator
var bus = DependencyResolver.Current.
GetService<IServiceBus>();
// return the queried result
return bus.Request<Membership.Queries.CurrentMember>(user);
}
}
}
当前成员只需通过查询对象获取,发送到IServiceBus
。 (这是一个自定义服务总线,而不是一个开源项目)。
/// <summary>
/// Resolves the currently authenticated <see cref="Member"/>.
/// </summary>
public class CurrentMember : IRequestFor<System.Security.Principal.IPrincipal, Member>
{
private readonly ISession session;
public CurrentMember(ISession session) {
this.session = session;
}
public Member Reply(System.Security.Principal.IPrincipal Model)
{
// if the user is not authenticated, then we should
// not have made it this far, and error out gracefully.
if (!Model.Identity.IsAuthenticated)
return null;
return session.Query<Member>()
.Where(context => context.Email == Model.Identity.Name)
.Take(1)
.SingleOrDefault();
}
}
以下是Request<T>
实施..
public dynamic Request<T>(dynamic message)
{
dynamic implementation = kernel.Get<T>();
return implementation.Reply(message);
}
答案 0 :(得分:2)
您应该将会话设置为FlushAction.Never
使用会话加载的对象将在一次性使用时刷新。
此外,还有奖励性能提升,因为会话不需要检查所有加载对象的状态。 这在加载大量数据的情况下非常重要。
答案 1 :(得分:1)
我注意到对象是隐式保存在Flush或Commit(?)上的。当我在我的类中有一个像int这样的非可空类型并且在数据库中可以为空时,这种行为总是会出现(在我的情况下)。 get拉出一个null,初始化为0,然后我得到一个隐式更新而不调用该类的save或update,因为实体已经改变了。