Я собираюсь закинуть свой сайт с помощью профилировщика nhibernate, и я получил это сообщение
Предупреждение: использование неявных транзакций не рекомендуется
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 транзакцией, подобной моей с моим коммитом?
Редактировать
Как мне обернуть операторы select транзакцией?Будет ли это так?Но тогда «транзакция» никогда не используется.
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;
}
}
Я могу избавиться от ошибок, но могу получить неожиданные результаты.
Например, когда я возвращаю OrderHistories обратно, я перебираю все из них и преобразовываю«Дата покупки» для пользователей местного времени.Это делается с помощью метода расширения, который я создал для своего списка.
После преобразования я установил его так, чтобы он переопределял «дату покупки» в объекте.Таким образом, мне не нужно создавать новый объект для одного изменения поля.
Теперь, если я выполняю это преобразование дат перед вызовом commit, nhibernate думает, что я обновил объект и должен его зафиксировать.
Итак, я вознаграждаю за этот вопрос.
- Как я могу создать свои методы, чтобы мне не нужно было оборачивать каждый метод в транзакции?Я уже использую ninject для своих сессий, так что, возможно, я смогу использовать это, хотя иногда, когда я вынужден делать несколько транзакций в одном запросе.
Так что я не знаю, иметь только одну транзакцию назапрос - это душа.
как я могу убедиться, что объекты, которые я изменяю для временного использования, случайно не получают коммит?
как мне выполнить отложенную загрузку, которую я использую в своем слое обслуживания.Я не хочу окружать мои ленивые загрузочные материалы транзакцией, поскольку они обычно используются в моем слое обслуживания.
Мне очень трудно найти примеры того, как это сделать, когдавы используете шаблон хранилища.В примерах все всегда написано в одной и той же транзакции, и я не хочу, чтобы транзакции были на моем сервисном уровне (это работа репо, а не моя бизнес-логика)