我要用 nhibernate profiler 扔掉我的网站,我收到了这条消息
警告:不鼓励使用隐式事务
http://nhprof.com/Learn/Alerts/DoNotUseImplicitTransactions
我看到它们出现在每一个 select 语句中。
private readonly ISession session;
public OrderHistoryRepo(ISession session)
{
this.session = session;
}
public void Save(OrderHistory orderHistory)
{
session.Save(orderHistory);
}
public List<OrderHistory> GetOrderHistory(Guid Id)
{
List<OrderHistory> orderHistories = session.Query<OrderHistory>().Where(x => x.Id == Id).ToList();
return orderHistories;
}
public void Commit()
{
using (ITransaction transaction = session.BeginTransaction())
{
transaction.Commit();
}
}
我是否应该像提交时一样使用事务来包装我的 GetOrderHistory?
编辑
我如何将选择语句与事务包装在一起?会是这样吗?但是从不使用“事务”。
public List<OrderHistory> GetOrderHistory(Guid Id)
{
using (ITransaction transaction = session.BeginTransaction())
{
List<OrderHistory> orderHistories = session.Query<OrderHistory>().Where(x => x.Id == Id).ToList();
return orderHistories;
}
}
编辑
Ninject(也许我可以利用它来帮助我,就像我在获得会话时所做的那样)
public class NhibernateSessionFactory
{
public ISessionFactory GetSessionFactory()
{
ISessionFactory fluentConfiguration = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c.FromConnectionStringWithKey("ConnectionString")))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Map>().Conventions.Add(ForeignKey.EndsWith("Id")))
.ExposeConfiguration(cfg => cfg.SetProperty("adonet.batch_size", "20"))
//.ExposeConfiguration(BuidSchema)
.BuildSessionFactory();
return fluentConfiguration;
}
private static void BuidSchema(NHibernate.Cfg.Configuration config)
{
new NHibernate.Tool.hbm2ddl.SchemaExport(config).Create(false, true);
}
}
public class NhibernateSessionFactoryProvider : Provider<ISessionFactory>
{
protected override ISessionFactory CreateInstance(IContext context)
{
var sessionFactory = new NhibernateSessionFactory();
return sessionFactory.GetSessionFactory();
}
}
public class NhibernateModule : NinjectModule
{
public override void Load()
{
Bind<ISessionFactory>().ToProvider<NhibernateSessionFactoryProvider>().InSingletonScope();
Bind<ISession>().ToMethod(context => context.Kernel.Get<ISessionFactory>().OpenSession()).InRequestScope();
}
}
编辑 3
如果我这样做
public List<OrderHistory> GetOrderHistory(Guid Id)
{
using (ITransaction transaction = session.BeginTransaction())
{
List<OrderHistory> orderHistories = session.Query<OrderHistory>().Where(x => x.Id == Id).ToList();
return orderHistories;
}
}
我收到此警报
如果我这样做
public List<OrderHistory> GetOrderHistory(Guid Id)
{
using (ITransaction transaction = session.BeginTransaction())
{
List<OrderHistory> orderHistories = session.Query<OrderHistory>().Where(x => x.Id == Id).ToList().ConvertToLocalTime(timezoneId);
transaction.Commit();
return orderHistories;
}
}
我可以摆脱错误,但可以得到意想不到的结果。
例如,当我返回 orderHistory 时,我会遍历所有这些并将“购买日期”转换为用户本地时间。这是通过我为列表创建的扩展方法完成的。
转换后,我将其设置为覆盖对象中的“购买日期”。这样,我不必为字段的一次更改创建新对象。
现在,如果我在调用提交之前进行日期转换,nhibernate 认为我已经更新了对象并需要提交它。
所以我在这个问题上悬赏。
- 如何创建我的方法,这样我就不必将每个方法包装在事务中?我已经在我的会话中使用了 ninject,所以也许我可以利用它,但有时我不得不在一个请求中执行多个事务。
所以我不知道每个请求只有一个交易是一个灵魂。
如何确保我为临时使用而更改的对象不会意外提交?
我如何才能在我的服务层中使用延迟加载。我不想在事务中包含我的延迟加载内容,因为它通常用于我的服务层。
当您使用存储库模式时,我发现很难找到如何做到这一点的示例。有了这些例子,一切都写在同一个事务中,我不想在我的服务层有事务(这是回购的工作而不是我的业务逻辑)