namespace Hims.Domain.Repositories.Dapper
{
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Linq.Expressions;
    using System.Threading.Tasks;
    using Hims.Domain.Entities;
    using SqlGenerator;

    /// <summary>
    /// The DapperRepository interface.
    /// </summary>
    /// <typeparam name="TEntity">
    /// The entity.
    /// </typeparam>
    public interface IDapperRepository<TEntity> where TEntity : class
    {
        /// <summary>
        /// Gets the connection.
        /// </summary>
        IDbConnection Connection { get; }

        /// <summary>
        /// Gets the sql generator.
        /// </summary>
        ISqlGenerator<TEntity> SqlGenerator { get; }

        /// <summary>
        /// Get number of rows
        /// </summary>
        /// <returns>
        /// The <see cref="int"/>.
        /// </returns>
        int Count();

        /// <summary>
        /// Get number of rows
        /// </summary>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="int"/>.
        /// </returns>
        int Count(IDbTransaction transaction);

        /// <summary>
        /// Get number of rows with WHERE clause
        /// </summary>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <returns>
        /// The <see cref="int"/>.
        /// </returns>
        int Count(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// Get number of rows with WHERE clause
        /// </summary>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="int"/>.
        /// </returns>
        int Count(Expression<Func<TEntity, bool>> predicate, IDbTransaction transaction);

        /// <summary>
        /// Get number of rows with DISTINCT clause
        /// </summary>
        /// <param name="distinctField">
        /// The distinct Field.
        /// </param>
        /// <returns>
        /// The <see cref="int"/>.
        /// </returns>
        int Count(Expression<Func<TEntity, object>> distinctField);

        /// <summary>
        /// Get number of rows with DISTINCT clause
        /// </summary>
        /// <param name="distinctField">
        /// The distinct Field.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="int"/>.
        /// </returns>
        int Count(Expression<Func<TEntity, object>> distinctField, IDbTransaction transaction);

        /// <summary>
        /// Get number of rows with DISTINCT and WHERE clause
        /// </summary>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="distinctField">
        /// The distinct Field.
        /// </param>
        /// <returns>
        /// The <see cref="int"/>.
        /// </returns>
        int Count(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, object>> distinctField);

        /// <summary>
        /// Get number of rows with DISTINCT and WHERE clause
        /// </summary>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="distinctField">
        /// The distinct Field.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="int"/>.
        /// </returns>
        int Count(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, object>> distinctField, IDbTransaction transaction);

        /// <summary>
        /// Get number of rows
        /// </summary>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> CountAsync();

        /// <summary>
        /// Get number of rows
        /// </summary>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> CountAsync(IDbTransaction transaction);

        /// <summary>
        /// Get number of rows with WHERE clause
        /// </summary>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// Get number of rows with WHERE clause
        /// </summary>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate, IDbTransaction transaction);

        /// <summary>
        /// Get number of rows with DISTINCT clause
        /// </summary>
        /// <param name="distinctField">
        /// The distinct Field.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> CountAsync(Expression<Func<TEntity, object>> distinctField);

        /// <summary>
        /// Get number of rows with DISTINCT clause
        /// </summary>
        /// <param name="distinctField">
        /// The distinct Field.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> CountAsync(Expression<Func<TEntity, object>> distinctField, IDbTransaction transaction);

        /// <summary>
        /// Get number of rows with DISTINCT and WHERE clause
        /// </summary>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="distinctField">
        /// The distinct Field.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, object>> distinctField);

        /// <summary>
        /// Get number of rows with DISTINCT and WHERE clause
        /// </summary>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="distinctField">
        /// The distinct Field.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, object>> distinctField, IDbTransaction transaction);

        /// <summary>
        /// Get first object
        /// </summary>
        /// <returns>
        /// The entity.
        /// </returns>
        TEntity Find();

        /// <summary>
        /// Get first object
        /// </summary>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <returns>
        /// The entity.
        /// </returns>
        TEntity Find(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// Get first object
        /// </summary>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The entity.
        /// </returns>
        TEntity Find(IDbTransaction transaction);

        /// <summary>
        /// Get first object
        /// </summary>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The entity.
        /// </returns>
        TEntity Find(Expression<Func<TEntity, bool>> predicate, IDbTransaction transaction);

        /// <summary>
        /// Get first object with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The entity.
        /// </returns>
        TEntity Find<TChild1>(
            Expression<Func<TEntity, bool>> predicate,
            Expression<Func<TEntity, object>> entity1,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get first object with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The entity.
        /// </returns>
        TEntity Find<TChild1, TChild2>(
            Expression<Func<TEntity, bool>> predicate,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get first object with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <typeparam name="TChild3">
        /// The child 3.
        /// </typeparam>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="entity3">
        /// The t Child 3.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The entity.
        /// </returns>
        TEntity Find<TChild1, TChild2, TChild3>(
            Expression<Func<TEntity, bool>> predicate,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            Expression<Func<TEntity, object>> entity3,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get first object with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <typeparam name="TChild3">
        /// The child 3.
        /// </typeparam>
        /// <typeparam name="TChild4">
        /// The child 4.
        /// </typeparam>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="entity3">
        /// The t Child 3.
        /// </param>
        /// <param name="entity4">
        /// The t Child 4.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The entity.
        /// </returns>
        TEntity Find<TChild1, TChild2, TChild3, TChild4>(
            Expression<Func<TEntity, bool>> predicate,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            Expression<Func<TEntity, object>> entity3,
            Expression<Func<TEntity, object>> entity4,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get first object with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <typeparam name="TChild3">
        /// The child 3.
        /// </typeparam>
        /// <typeparam name="TChild4">
        /// The child 4.
        /// </typeparam>
        /// <typeparam name="TChild5">
        /// The child 5.
        /// </typeparam>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="entity3">
        /// The t Child 3.
        /// </param>
        /// <param name="entity4">
        /// The t Child 4.
        /// </param>
        /// <param name="entity5">
        /// The t Child 5.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The entity.
        /// </returns>
        TEntity Find<TChild1, TChild2, TChild3, TChild4, TChild5>(
            Expression<Func<TEntity, bool>> predicate,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            Expression<Func<TEntity, object>> entity3,
            Expression<Func<TEntity, object>> entity4,
            Expression<Func<TEntity, object>> entity5,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get first object with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <typeparam name="TChild3">
        /// The child 3.
        /// </typeparam>
        /// <typeparam name="TChild4">
        /// The child 4.
        /// </typeparam>
        /// <typeparam name="TChild5">
        /// The child 5.
        /// </typeparam>
        /// <typeparam name="TChild6">
        /// The child 6.
        /// </typeparam>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="entity3">
        /// The t Child 3.
        /// </param>
        /// <param name="entity4">
        /// The t Child 4.
        /// </param>
        /// <param name="entity5">
        /// The t Child 5.
        /// </param>
        /// <param name="entity6">
        /// The t Child 6.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The entity.
        /// </returns>
        TEntity Find<TChild1, TChild2, TChild3, TChild4, TChild5, TChild6>(
            Expression<Func<TEntity, bool>> predicate,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            Expression<Func<TEntity, object>> entity3,
            Expression<Func<TEntity, object>> entity4,
            Expression<Func<TEntity, object>> entity5,
            Expression<Func<TEntity, object>> entity6,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get object by Id
        /// </summary>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <returns>
        /// The entity.
        /// </returns>
        TEntity FindById(object id);

        /// <summary>
        /// Get object by Id
        /// </summary>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The entity.
        /// </returns>
        TEntity FindById(object id, IDbTransaction transaction);

        /// <summary>
        /// Get object by Id with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The entity.
        /// </returns>
        TEntity FindById<TChild1>(object id, Expression<Func<TEntity, object>> entity1, IDbTransaction transaction = null);

        /// <summary>
        /// Get object by Id with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The entity.
        /// </returns>
        TEntity FindById<TChild1, TChild2>(
            object id,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get object by Id with join objects
        /// </summary>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="entity1">
        /// The t child 1.
        /// </param>
        /// <param name="entity2">
        /// The t child 2.
        /// </param>
        /// <param name="entity3">
        /// The t child 3.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <typeparam name="TChild3">
        /// The child 3.
        /// </typeparam>
        /// <returns>
        /// The entity.
        /// </returns>
        TEntity FindById<TChild1, TChild2, TChild3>(
            object id,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            Expression<Func<TEntity, object>> entity3,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get object by Id with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <typeparam name="TChild3">
        /// The child 3.
        /// </typeparam>
        /// <typeparam name="TChild4">
        /// The child 4.
        /// </typeparam>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="entity3">
        /// The t Child 3.
        /// </param>
        /// <param name="entity4">
        /// The t Child 4.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The entity.
        /// </returns>
        TEntity FindById<TChild1, TChild2, TChild3, TChild4>(
            object id,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            Expression<Func<TEntity, object>> entity3,
            Expression<Func<TEntity, object>> entity4,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get object by Id with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <typeparam name="TChild3">
        /// The child 3.
        /// </typeparam>
        /// <typeparam name="TChild4">
        /// The child 4.
        /// </typeparam>
        /// <typeparam name="TChild5">
        /// The child 5.
        /// </typeparam>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="entity3">
        /// The t Child 3.
        /// </param>
        /// <param name="entity4">
        /// The t Child 4.
        /// </param>
        /// <param name="entity5">
        /// The t Child 5.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The entity.
        /// </returns>
        TEntity FindById<TChild1, TChild2, TChild3, TChild4, TChild5>(
            object id,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            Expression<Func<TEntity, object>> entity3,
            Expression<Func<TEntity, object>> entity4,
            Expression<Func<TEntity, object>> entity5,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get object by Id with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The t child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The t child 2.
        /// </typeparam>
        /// <typeparam name="TChild3">
        /// The t child 3.
        /// </typeparam>
        /// <typeparam name="TChild4">
        /// The t child 4.
        /// </typeparam>
        /// <typeparam name="TChild5">
        /// The t child 5.
        /// </typeparam>
        /// <typeparam name="TChild6">
        /// The t child 6.
        /// </typeparam>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="entity1">
        /// The child 1.
        /// </param>
        /// <param name="entity2">
        /// The child 2.
        /// </param>
        /// <param name="entity3">
        /// The child 3.
        /// </param>
        /// <param name="entity4">
        /// The child 4.
        /// </param>
        /// <param name="entity5">
        /// The child 5.
        /// </param>
        /// <param name="entity6">
        /// The child 6.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The entity.
        /// </returns>
        TEntity FindById<TChild1, TChild2, TChild3, TChild4, TChild5, TChild6>(
            object id,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            Expression<Func<TEntity, object>> entity3,
            Expression<Func<TEntity, object>> entity4,
            Expression<Func<TEntity, object>> entity5,
            Expression<Func<TEntity, object>> entity6,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get object by Id
        /// </summary>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<TEntity> FindByIdAsync(object id);

        /// <summary>
        /// Get object by Id
        /// </summary>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<TEntity> FindByIdAsync(object id, IDbTransaction transaction);

        /// <summary>
        /// Get object by Id with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<TEntity> FindByIdAsync<TChild1>(object id, Expression<Func<TEntity, object>> entity1, IDbTransaction transaction = null);

        /// <summary>
        /// Get object by Id with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<TEntity> FindByIdAsync<TChild1, TChild2>(
            object id,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get object by Id with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <typeparam name="TChild3">
        /// The child 3.
        /// </typeparam>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="entity3">
        /// The t Child 3.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<TEntity> FindByIdAsync<TChild1, TChild2, TChild3>(
            object id,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            Expression<Func<TEntity, object>> entity3,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get object by Id with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <typeparam name="TChild3">
        /// The child 3.
        /// </typeparam>
        /// <typeparam name="TChild4">
        /// The child 4.
        /// </typeparam>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="entity3">
        /// The t Child 3.
        /// </param>
        /// <param name="entity4">
        /// The t Child 4.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<TEntity> FindByIdAsync<TChild1, TChild2, TChild3, TChild4>(
            object id,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            Expression<Func<TEntity, object>> entity3,
            Expression<Func<TEntity, object>> entity4,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get object by Id with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <typeparam name="TChild3">
        /// The child 3.
        /// </typeparam>
        /// <typeparam name="TChild4">
        /// The child 4.
        /// </typeparam>
        /// <typeparam name="TChild5">
        /// The child 5.
        /// </typeparam>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="entity3">
        /// The t Child 3.
        /// </param>
        /// <param name="entity4">
        /// The t Child 4.
        /// </param>
        /// <param name="entity5">
        /// The t Child 5.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<TEntity> FindByIdAsync<TChild1, TChild2, TChild3, TChild4, TChild5>(
            object id,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            Expression<Func<TEntity, object>> entity3,
            Expression<Func<TEntity, object>> entity4,
            Expression<Func<TEntity, object>> entity5,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get object by Id with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <typeparam name="TChild3">
        /// The child 3.
        /// </typeparam>
        /// <typeparam name="TChild4">
        /// The child 4.
        /// </typeparam>
        /// <typeparam name="TChild5">
        /// The child 5.
        /// </typeparam>
        /// <typeparam name="TChild6">
        /// The child 6.
        /// </typeparam>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="entity3">
        /// The t Child 3.
        /// </param>
        /// <param name="entity4">
        /// The t Child 4.
        /// </param>
        /// <param name="entity5">
        /// The t Child 5.
        /// </param>
        /// <param name="entity6">
        /// The t Child 6.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<TEntity> FindByIdAsync<TChild1, TChild2, TChild3, TChild4, TChild5, TChild6>(
            object id,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            Expression<Func<TEntity, object>> entity3,
            Expression<Func<TEntity, object>> entity4,
            Expression<Func<TEntity, object>> entity5,
            Expression<Func<TEntity, object>> entity6,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get first object
        /// </summary>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<TEntity> FindAsync();

        /// <summary>
        /// Get first object
        /// </summary>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<TEntity> FindAsync(IDbTransaction transaction);

        /// <summary>
        /// Get first object
        /// </summary>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<TEntity> FindAsync(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        /// Get first object
        /// </summary>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<TEntity> FindAsync(Expression<Func<TEntity, bool>> predicate, IDbTransaction transaction);

        /// <summary>
        /// Get first object with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<TEntity> FindAsync<TChild1>(
            Expression<Func<TEntity, bool>> predicate,
            Expression<Func<TEntity, object>> entity1,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get first object with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<TEntity> FindAsync<TChild1, TChild2>(
            Expression<Func<TEntity, bool>> predicate,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get first object with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <typeparam name="TChild3">
        /// The child 3.
        /// </typeparam>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="entity3">
        /// The t Child 3.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<TEntity> FindAsync<TChild1, TChild2, TChild3>(
            Expression<Func<TEntity, bool>> predicate,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            Expression<Func<TEntity, object>> entity3,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get first object with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <typeparam name="TChild3">
        /// The child 3.
        /// </typeparam>
        /// <typeparam name="TChild4">
        /// The child 4.
        /// </typeparam>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="entity3">
        /// The t Child 3.
        /// </param>
        /// <param name="entity4">
        /// The t Child 4.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<TEntity> FindAsync<TChild1, TChild2, TChild3, TChild4>(
            Expression<Func<TEntity, bool>> predicate,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            Expression<Func<TEntity, object>> entity3,
            Expression<Func<TEntity, object>> entity4,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get first object with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <typeparam name="TChild3">
        /// The child 3.
        /// </typeparam>
        /// <typeparam name="TChild4">
        /// The child 4.
        /// </typeparam>
        /// <typeparam name="TChild5">
        /// The child 5.
        /// </typeparam>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="entity3">
        /// The t Child 3.
        /// </param>
        /// <param name="entity4">
        /// The t Child 4.
        /// </param>
        /// <param name="entity5">
        /// The t Child 5.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<TEntity> FindAsync<TChild1, TChild2, TChild3, TChild4, TChild5>(
            Expression<Func<TEntity, bool>> predicate,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            Expression<Func<TEntity, object>> entity3,
            Expression<Func<TEntity, object>> entity4,
            Expression<Func<TEntity, object>> entity5,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get first object with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <typeparam name="TChild3">
        /// The child 3.
        /// </typeparam>
        /// <typeparam name="TChild4">
        /// The child 4.
        /// </typeparam>
        /// <typeparam name="TChild5">
        /// The child 5.
        /// </typeparam>
        /// <typeparam name="TChild6">
        /// The child 6.
        /// </typeparam>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="entity3">
        /// The t Child 3.
        /// </param>
        /// <param name="entity4">
        /// The t Child 4.
        /// </param>
        /// <param name="entity5">
        /// The t Child 5.
        /// </param>
        /// <param name="entity6">
        /// The t Child 6.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<TEntity> FindAsync<TChild1, TChild2, TChild3, TChild4, TChild5, TChild6>(
            Expression<Func<TEntity, bool>> predicate,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            Expression<Func<TEntity, object>> entity3,
            Expression<Func<TEntity, object>> entity4,
            Expression<Func<TEntity, object>> entity5,
            Expression<Func<TEntity, object>> entity6,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get all objects
        /// </summary>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable{T}"/>.
        /// </returns>
        IEnumerable<TEntity> FindAll(IDbTransaction transaction = null);

        /// <summary>
        /// Get all objects
        /// </summary>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable{T}"/>.
        /// </returns>
        IEnumerable<TEntity> FindAll(Expression<Func<TEntity, bool>> predicate, IDbTransaction transaction = null);

        /// <summary>
        /// Get all objects with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable{T}"/>.
        /// </returns>
        IEnumerable<TEntity> FindAll<TChild1>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, object>> entity1, IDbTransaction transaction = null);

        /// <summary>
        /// Get all objects with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable{T}"/>.
        /// </returns>
        IEnumerable<TEntity> FindAll<TChild1, TChild2>(
            Expression<Func<TEntity, bool>> predicate,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get all objects with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <typeparam name="TChild3">
        /// The child 3.
        /// </typeparam>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="entity3">
        /// The t Child 3.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable{T}"/>.
        /// </returns>
        IEnumerable<TEntity> FindAll<TChild1, TChild2, TChild3>(
            Expression<Func<TEntity, bool>> predicate,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            Expression<Func<TEntity, object>> entity3,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get all objects with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <typeparam name="TChild3">
        /// The child 3.
        /// </typeparam>
        /// <typeparam name="TChild4">
        /// The child 4.
        /// </typeparam>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="entity3">
        /// The t Child 3.
        /// </param>
        /// <param name="entity4">
        /// The t Child 4.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable{T}"/>.
        /// </returns>
        IEnumerable<TEntity> FindAll<TChild1, TChild2, TChild3, TChild4>(
            Expression<Func<TEntity, bool>> predicate,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            Expression<Func<TEntity, object>> entity3,
            Expression<Func<TEntity, object>> entity4,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get all objects with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <typeparam name="TChild3">
        /// The child 3.
        /// </typeparam>
        /// <typeparam name="TChild4">
        /// The child 4.
        /// </typeparam>
        /// <typeparam name="TChild5">
        /// The child 5.
        /// </typeparam>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="entity3">
        /// The t Child 3.
        /// </param>
        /// <param name="entity4">
        /// The t Child 4.
        /// </param>
        /// <param name="entity5">
        /// The t Child 5.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable{T}"/>.
        /// </returns>
        IEnumerable<TEntity> FindAll<TChild1, TChild2, TChild3, TChild4, TChild5>(
            Expression<Func<TEntity, bool>> predicate,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            Expression<Func<TEntity, object>> entity3,
            Expression<Func<TEntity, object>> entity4,
            Expression<Func<TEntity, object>> entity5,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get all objects with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <typeparam name="TChild3">
        /// The child 3.
        /// </typeparam>
        /// <typeparam name="TChild4">
        /// The child 4.
        /// </typeparam>
        /// <typeparam name="TChild5">
        /// The child 5.
        /// </typeparam>
        /// <typeparam name="TChild6">
        /// The child 6.
        /// </typeparam>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="entity3">
        /// The t Child 3.
        /// </param>
        /// <param name="entity4">
        /// The t Child 4.
        /// </param>
        /// <param name="entity5">
        /// The t Child 5.
        /// </param>
        /// <param name="entity6">
        /// The t Child 6.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable{T}"/>.
        /// </returns>
        IEnumerable<TEntity> FindAll<TChild1, TChild2, TChild3, TChild4, TChild5, TChild6>(
            Expression<Func<TEntity, bool>> predicate,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            Expression<Func<TEntity, object>> entity3,
            Expression<Func<TEntity, object>> entity4,
            Expression<Func<TEntity, object>> entity5,
            Expression<Func<TEntity, object>> entity6,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get all objects
        /// </summary>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<TEntity>> FindAllAsync(IDbTransaction transaction = null);

        /// <summary>
        /// Get all objects
        /// </summary>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<TEntity>> FindAllAsync(Expression<Func<TEntity, bool>> predicate, IDbTransaction transaction = null);

        /// <summary>
        /// Get all objects with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<TEntity>> FindAllAsync<TChild1>(
            Expression<Func<TEntity, bool>> predicate,
            Expression<Func<TEntity, object>> entity1,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get all objects with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<TEntity>> FindAllAsync<TChild1, TChild2>(
            Expression<Func<TEntity, bool>> predicate,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get all objects with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <typeparam name="TChild3">
        /// The child 3.
        /// </typeparam>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="entity3">
        /// The t Child 3.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<TEntity>> FindAllAsync<TChild1, TChild2, TChild3>(
            Expression<Func<TEntity, bool>> predicate,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            Expression<Func<TEntity, object>> entity3,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get all objects with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <typeparam name="TChild3">
        /// The child 3.
        /// </typeparam>
        /// <typeparam name="TChild4">
        /// The child 4.
        /// </typeparam>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="entity3">
        /// The t Child 3.
        /// </param>
        /// <param name="entity4">
        /// The t Child 4.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<TEntity>> FindAllAsync<TChild1, TChild2, TChild3, TChild4>(
            Expression<Func<TEntity, bool>> predicate,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            Expression<Func<TEntity, object>> entity3,
            Expression<Func<TEntity, object>> entity4,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get all objects with join objects
        /// </summary>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <typeparam name="TChild3">
        /// The child 3.
        /// </typeparam>
        /// <typeparam name="TChild4">
        /// The child 4.
        /// </typeparam>
        /// <typeparam name="TChild5">
        /// The child 5.
        /// </typeparam>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="entity1">
        /// The t Child 1.
        /// </param>
        /// <param name="entity2">
        /// The t Child 2.
        /// </param>
        /// <param name="entity3">
        /// The t Child 3.
        /// </param>
        /// <param name="entity4">
        /// The t Child 4.
        /// </param>
        /// <param name="entity5">
        /// The t Child 5.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<TEntity>> FindAllAsync<TChild1, TChild2, TChild3, TChild4, TChild5>(
            Expression<Func<TEntity, bool>> predicate,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            Expression<Func<TEntity, object>> entity3,
            Expression<Func<TEntity, object>> entity4,
            Expression<Func<TEntity, object>> entity5,
            IDbTransaction transaction = null);

        /// <summary>
        /// The find all async.
        /// </summary>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="entity1">
        /// The entity 1.
        /// </param>
        /// <param name="entity2">
        /// The entity 2.
        /// </param>
        /// <param name="entity3">
        /// The entity 3.
        /// </param>
        /// <param name="entity4">
        /// The entity 4.
        /// </param>
        /// <param name="entity5">
        /// The entity 5.
        /// </param>
        /// <param name="entity6">
        /// The entity 6.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <typeparam name="TChild1">
        /// The child 1.
        /// </typeparam>
        /// <typeparam name="TChild2">
        /// The child 2.
        /// </typeparam>
        /// <typeparam name="TChild3">
        /// The child 3.
        /// </typeparam>
        /// <typeparam name="TChild4">
        /// The child 4.
        /// </typeparam>
        /// <typeparam name="TChild5">
        /// The child 5.
        /// </typeparam>
        /// <typeparam name="TChild6">
        /// The child 6.
        /// </typeparam>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<TEntity>> FindAllAsync<TChild1, TChild2, TChild3, TChild4, TChild5, TChild6>(
            Expression<Func<TEntity, bool>> predicate,
            Expression<Func<TEntity, object>> entity1,
            Expression<Func<TEntity, object>> entity2,
            Expression<Func<TEntity, object>> entity3,
            Expression<Func<TEntity, object>> entity4,
            Expression<Func<TEntity, object>> entity5,
            Expression<Func<TEntity, object>> entity6,
            IDbTransaction transaction = null);

        /// <summary>
        /// Insert object to DB
        /// </summary>
        /// <param name="instance">
        /// The instance.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        bool Insert(TEntity instance);

        /// <summary>
        /// Insert object to DB
        /// </summary>
        /// <param name="instance">
        /// The instance.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        bool Insert(TEntity instance, IDbTransaction transaction);

        /// <summary>
        /// Insert object to DB
        /// </summary>
        /// <param name="instance">
        ///     The instance.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> InsertAsync(TEntity instance);

        /// <summary>
        /// Insert object to DB
        /// </summary>
        /// <param name="instance">
        /// The instance.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> InsertAsync(TEntity instance, IDbTransaction transaction);

        /// <summary>
        /// Bulk Insert objects to DB
        /// </summary>
        /// <param name="instances">
        /// The instances.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="int"/>.
        /// </returns>
        int BulkInsert(IEnumerable<TEntity> instances, IDbTransaction transaction = null);

        /// <summary>
        /// Bulk Insert objects to DB
        /// </summary>
        /// <param name="instances">
        /// The instances.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> BulkInsertAsync(IEnumerable<TEntity> instances, IDbTransaction transaction = null);

        /// <summary>
        /// Delete object from DB
        /// </summary>
        /// <param name="instance">
        /// The instance.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        bool Delete(TEntity instance, IDbTransaction transaction = null);

        /// <summary>
        /// Delete object from DB
        /// </summary>
        /// <param name="instance">
        /// The instance.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<bool> DeleteAsync(TEntity instance, IDbTransaction transaction = null);

        /// <summary>
        /// Delete objects from DB
        /// </summary>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        bool Delete(Expression<Func<TEntity, bool>> predicate, IDbTransaction transaction = null);

        /// <summary>
        /// Delete objects from DB
        /// </summary>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<bool> DeleteAsync(Expression<Func<TEntity, bool>> predicate, IDbTransaction transaction = null);

        /// <summary>
        /// Update object in DB
        /// </summary>
        /// <param name="instance">
        /// The instance.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        bool Update(TEntity instance);

        /// <summary>
        /// Update object in DB
        /// </summary>
        /// <param name="instance">
        /// The instance.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        bool Update(TEntity instance, IDbTransaction transaction);

        /// <summary>
        /// Update object in DB
        /// </summary>
        /// <param name="instance">
        /// The instance.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> UpdateAsync(TEntity instance);

        /// <summary>
        /// Update object in DB
        /// </summary>
        /// <param name="instance">
        /// The instance.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<int> UpdateAsync(TEntity instance, IDbTransaction transaction);

        /// <summary>
        /// Update object in DB
        /// </summary>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="instance">
        /// The instance.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        bool Update(Expression<Func<TEntity, bool>> predicate, TEntity instance);

        /// <summary>
        /// Update object in DB
        /// </summary>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="instance">
        /// The instance.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        bool Update(Expression<Func<TEntity, bool>> predicate, TEntity instance, IDbTransaction transaction);

        /// <summary>
        /// Update object in DB
        /// </summary>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="instance">
        /// The instance.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<bool> UpdateAsync(Expression<Func<TEntity, bool>> predicate, TEntity instance);

        /// <summary>
        /// Update object in DB
        /// </summary>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="instance">
        /// The instance.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<bool> UpdateAsync(Expression<Func<TEntity, bool>> predicate, TEntity instance, IDbTransaction transaction);

        /// <summary>
        /// Bulk Update objects in DB
        /// </summary>
        /// <param name="instances">
        /// The instances.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<bool> BulkUpdateAsync(IEnumerable<TEntity> instances);

        /// <summary>
        /// Bulk Update objects in DB
        /// </summary>
        /// <param name="instances">
        /// The instances.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<bool> BulkUpdateAsync(IEnumerable<TEntity> instances, IDbTransaction transaction);

        /// <summary>
        /// Bulk Update objects in DB
        /// </summary>
        /// <param name="instances">
        /// The instances.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        bool BulkUpdate(IEnumerable<TEntity> instances);

        /// <summary>
        /// Bulk Update objects in DB
        /// </summary>
        /// <param name="instances">
        /// The instances.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        bool BulkUpdate(IEnumerable<TEntity> instances, IDbTransaction transaction);

        /// <summary>
        /// Get all objects with BETWEEN query
        /// </summary>
        /// <param name="from">
        /// The from.
        /// </param>
        /// <param name="to">
        /// The to.
        /// </param>
        /// <param name="btwField">
        /// The btw Field.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable{T}"/>.
        /// </returns>
        IEnumerable<TEntity> FindAllBetween(object from, object to, Expression<Func<TEntity, object>> btwField, IDbTransaction transaction = null);

        /// <summary>
        /// Get all objects with BETWEEN query
        /// </summary>
        /// <param name="from">
        /// The from.
        /// </param>
        /// <param name="to">
        /// The to.
        /// </param>
        /// <param name="btwField">
        /// The btw Field.
        /// </param>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable{T}"/>.
        /// </returns>
        IEnumerable<TEntity> FindAllBetween(
            object from,
            object to,
            Expression<Func<TEntity, object>> btwField,
            Expression<Func<TEntity, bool>> predicate = null,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get all objects with BETWEEN query
        /// </summary>
        /// <param name="from">
        /// The from.
        /// </param>
        /// <param name="to">
        /// The to.
        /// </param>
        /// <param name="btwField">
        /// The btw Field.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable{T}"/>.
        /// </returns>
        IEnumerable<TEntity> FindAllBetween(DateTime from, DateTime to, Expression<Func<TEntity, object>> btwField, IDbTransaction transaction = null);

        /// <summary>
        /// Get all objects with BETWEEN query
        /// </summary>
        /// <param name="from">
        /// The from.
        /// </param>
        /// <param name="to">
        /// The to.
        /// </param>
        /// <param name="btwField">
        /// The btw Field.
        /// </param>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable{T}"/>.
        /// </returns>
        IEnumerable<TEntity> FindAllBetween(
            DateTime from,
            DateTime to,
            Expression<Func<TEntity, object>> btwField,
            Expression<Func<TEntity, bool>> predicate,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get all objects with BETWEEN query
        /// </summary>
        /// <param name="from">
        /// The from.
        /// </param>
        /// <param name="to">
        /// The to.
        /// </param>
        /// <param name="btwField">
        /// The btw Field.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<TEntity>> FindAllBetweenAsync(object from, object to, Expression<Func<TEntity, object>> btwField, IDbTransaction transaction = null);

        /// <summary>
        /// Get all objects with BETWEEN query
        /// </summary>
        /// <param name="from">
        /// The from.
        /// </param>
        /// <param name="to">
        /// The to.
        /// </param>
        /// <param name="btwField">
        /// The btw Field.
        /// </param>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<TEntity>> FindAllBetweenAsync(
            object from,
            object to,
            Expression<Func<TEntity, object>> btwField,
            Expression<Func<TEntity, bool>> predicate,
            IDbTransaction transaction = null);

        /// <summary>
        /// Get all objects with BETWEEN query
        /// </summary>
        /// <param name="from">
        /// The from.
        /// </param>
        /// <param name="to">
        /// The to.
        /// </param>
        /// <param name="btwField">
        /// The btw Field.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<TEntity>> FindAllBetweenAsync(DateTime from, DateTime to, Expression<Func<TEntity, object>> btwField, IDbTransaction transaction = null);

        /// <summary>
        /// Get all objects with BETWEEN query
        /// </summary>
        /// <param name="from">
        /// The from.
        /// </param>
        /// <param name="to">
        /// The to.
        /// </param>
        /// <param name="btwField">
        /// The btw Field.
        /// </param>
        /// <param name="predicate">
        /// The predicate.
        /// </param>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        Task<IEnumerable<TEntity>> FindAllBetweenAsync(
            DateTime from,
            DateTime to,
            Expression<Func<TEntity, object>> btwField,
            Expression<Func<TEntity, bool>> predicate,
            IDbTransaction transaction = null);
    }
}