c# async session nhibernate
NHibernate 5 now support the pattern
https://enterprisecraftsmanship.com/posts/nhibernate-async-support/
https://nhibernate.info/doc/nhibernate-reference/transactions.html
https://bartwullems.blogspot.com/2017/12/nhibernate-5asyncawait.html
https://codereview.stackexchange.com/questions/257665/how-to-make-a-good-session-handling-with-nhibernate
ISessionFactory sessions;
ISession session = sessions.OpenSession();
ITransaction tx = null;
try
{
tx = session.BeginTransaction())
Customer customer = await session.GetAsync<Customer>(1);
List<Customer> customers = await session.Query<Customer>().ToListAsync();
Customer customer = await session.Query<Customer>()
.Where(x => x.Name.Contains("Customer 1"))
.SingleOrDefaultAsync();
session.Save(customer);
tx.Commit();
}
catch (Exception)
{
if (tx != null) tx.Rollback();
session.Close();
throw;
}
finally {
session.disconnect();
}
Using async repository
----------------
public class ContractsController : ControllerBase
{
private readonly BaseRepository<Contract, int> contractRepository;
public ContractsController(BaseRepository<Contract, int> contractRepository)
{
this.contractRepository = contractRepository;
}
public async Task<IHttpActionResult> Get([FromODataUri] int key)
{
var contract = await contractRepository.FindOneAsync(key);
if (contract == null)
{
return StatusCode(HttpStatusCode.NotFound);
}
return Ok(contract);
}
}
Repository Impl (generic)
-----------------
public class BaseRepository<T,TId> : IRepository<T, TId> where T : class
{
protected ISession session = HttpContext.Current.Items["nhibernate.current_session"] as ISession;
protected ITransaction transaction = null;
public BaseRepository()
{
//session = NHibernateHelper.OpenSession();
transaction = session.BeginTransaction();
}
public async void Create(T entity)
{
await session.SaveOrUpdateAsync(entity);
await transaction.CommitAsync();
}
public async void DeleteAsync(TId key)
{
var entity = await session.LoadAsync<T>(key);
await session.DeleteAsync(entity);
await transaction.CommitAsync();
}
public async Task<List<T>> FindAllAsync()
{
return await session.Query<T>().ToListAsync();
}
public async Task<T> FindOneAsync(TId key)
{
return await session.GetAsync<T>(key);
}
public async void UpdateAsync(T entity)
{
await session.SaveOrUpdateAsync(entity);
await transaction.CommitAsync();
}
}
Getting Data async
-----------------
Customer customer = await session.GetAsync<Customer>(1);
List<Customer> customers = await session.Query<Customer>().ToListAsync();
Customer customer = await session.Query<Customer>()
.Where(x => x.Name.Contains("Customer 1"))
.SingleOrDefaultAsync();
Creating/Updating Data async
------------------
using (ISession session = sessionFactory.OpenSession())
using (ITransaction transaction = session.BeginTransaction())
{
Customer customer = await session.GetAsync<Customer>(1);
customer.Name = "Customer 3";
await session.SaveOrUpdateAsync(customer);
await transaction.CommitAsync();
}
nhibernate 5 feature
-----------------
private ISession _session;
public async Task<T> GetAsync<T>(int id) where T : ISomeEntity
{
return await _session.GetAsync<T>(id);
}
other simple ways
-----------------
NHibernate 5–Async/await
The introduction of async/await to optimize IO bound methods/operations.
// Usage ICriteria.ListAsync<T>()
var customers = await session
.CreateCriteria<Customer>()
.ListAsync<Customer>();
// Usage ICriteria.UniqueResultAsync<T>()
var customer = await session
.CreateCriteria<Customer>()
.Add(Restrictions.Eq("Name", "Ayende"))
.UniqueResultAsync<Customer>();
// Usage IQueryOver.ListAsync()
var person = await session
.QueryOver<Customer>()
.ListAsync();
// Usage IQueryOver.ListAsync<T>()
var person = await session
.QueryOver<Customer>()
.Select(p => p.Name)
.ListAsync<string>();
// Usage IQueryOver.SingleOrDefaultAsync<T>()
var customer = await session
.QueryOver<Customer>()
.SingleOrDefaultAsync();
//Usage of ISession.FlushAsync()
_session.FlushAsync(cancellationToken);