c# async session nhibernate code example

Example: 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);