/// <summary>An OrmConnection method that gets a scalar.</summary>
        /// <typeparam name="T">   Generic type parameter.</typeparam>
        /// <typeparam name="TKey">Type of the key.</typeparam>

        /// <param name="field">    The field.</param>
        /// <param name="predicate">The predicate.</param>
        /// <returns>The scalar.</returns>
        public TKey GetScalar <T, TKey>(Expression <Func <T, TKey> > field, Expression <Func <T, bool> > predicate)
        {
            //int maxAgeUnder50 = db.Scalar<Person, int>(x => Sql.Max(x.Age), x => x.Age < 50);
            var ev = DialectProvider.ExpressionVisitor <T>();

            return(this.ExecuteScalar <TKey>(DialectProvider.ToSelectStatement(ev.Where(predicate).Select(field), CommandFlags.None)));
        }
        /// <summary>An OrmConnection method that gets a scalar.</summary>
        /// <typeparam name="T">   Generic type parameter.</typeparam>
        /// <typeparam name="TKey">Type of the key.</typeparam>
        /// <param name="field"> The field.</param>
        /// <returns>The scalar.</returns>
        public async Task <TKey> GetScalarAsync <T, TKey>(Expression <Func <T, TKey> > field)
        {
            //int maxAgeUnder50 = db.Scalar<Person, int>(x => Sql.Max(x.Age));
            var ev = DialectProvider.ExpressionVisitor <T>();

            return(await this.ExecuteScalarAsync <TKey>(DialectProvider.ToSelectStatement(ev.Select(field), CommandFlags.None)));
        }
        /// <summary>An OrmConnection method that first or default.</summary>
        /// <typeparam name="T">Generic type parameter.</typeparam>
        /// <param name="predicate">The predicate.</param>
        /// <returns>A T.</returns>
        public async Task <T> FirstOrDefaultAsync <T>(Expression <Func <T, bool> > predicate)
        {
            var ev = DialectProvider.ExpressionVisitor <T>();
            var r  = await SelectAsync(ev.Where(predicate).Limit(1));

            return(r.FirstOrDefault());
        }
        /// <summary>An OrmConnection method that inserts an only.</summary>
        /// <typeparam name="T">Generic type parameter.</typeparam>
        /// <param name="obj">       The object.</param>
        /// <param name="onlyFields">The only fields.</param>
        public void InsertOnly <T>(T obj, SqlExpressionVisitor <T> onlyFields) where T : new()
        {
            var ev  = DialectProvider.ExpressionVisitor <T>();
            var sql = DialectProvider.ToInsertRowStatement(new[] { obj }, ev.InsertFields);

            this.Execute(sql);
        }
        /// <summary>
        /// Update only some fields of an object
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="model">Object to update</param>
        /// <param name="onlyFields">Specify the fields to update. ie : x=> x.SomeProperty1 or x=> new{ x.SomeProperty1, x.SomeProperty2}</param>
        /// <returns></returns>
        public int Update <T, TKey>(T model, Expression <Func <T, TKey> > onlyFields)
        {
            var ev = DialectProvider.ExpressionVisitor <T>();

            ev.Update(onlyFields);
            return(Update(model, ev));
        }
        public async Task <int> UpdateAsync <T, TKey>(T model, Expression <Func <T, TKey> > onlyFields)
        {
            var ev = DialectProvider.ExpressionVisitor <T>();

            ev.Update(onlyFields);
            return(await UpdateAsync(model, ev));
        }
        /// <summary>An OrmConnection method that inserts an only.</summary>
        /// <typeparam name="T">Generic type parameter.</typeparam>
        /// <param name="obj">       The object.</param>
        /// <param name="onlyFields">The only fields.</param>
        public async Task <int> InsertOnlyAsync <T>(T obj, SqlExpressionVisitor <T> onlyFields) where T : new()
        {
            var ev  = DialectProvider.ExpressionVisitor <T>();
            var sql = DialectProvider.ToInsertRowStatement(new[] { obj }, ev.InsertFields);

            return(await this.ExecuteAsync(sql));
        }
        /// <summary>An OrmConnection method that selects.</summary>
        /// <typeparam name="T">Generic type parameter.</typeparam>
        /// <param name="expression">The ev.</param>
        /// <param name="buffered"></param>
        /// <returns>A List&lt;T&gt;</returns>
        public IEnumerable <T> Select <T>(Func <SqlExpressionVisitor <T>, SqlExpressionVisitor <T> > expression,
                                          CommandFlags flags = CommandFlags.Buffered)
        {
            var ev = DialectProvider.ExpressionVisitor <T>();

            return(this.Query <T>(DialectProvider.ToSelectStatement(expression(ev), flags)));
        }
        /// <summary>An OrmConnection method that inserts an only.</summary>
        /// <typeparam name="T">Generic type parameter.</typeparam>
        /// <param name="obj">       The object.</param>
        /// <param name="onlyFields">The only fields.</param>
        public async Task <int> InsertOnlyAsync <T>(T obj, Func <SqlExpressionVisitor <T>, SqlExpressionVisitor <T> > onlyFields)
            where T : new()
        {
            var ev = DialectProvider.ExpressionVisitor <T>();

            return(await InsertOnlyAsync(obj, onlyFields(ev)));
        }
        /// <summary>An OrmConnection method that deletes this object.</summary>
        /// <typeparam name="T">Generic type parameter.</typeparam>
        /// <param name="where"> The where.</param>
        /// <returns>An int.</returns>
        public async Task <int> DeleteAllAsync <T>(Expression <Func <T, bool> > where = null)
        {
            var ev = DialectProvider.ExpressionVisitor <T>();

            if (where != null)
            {
                ev.Where(where);
            }
            return(await DeleteAllAsync(ev.Where(where)));
        }
        /// <param name="where"> The where.</param>
        /// <returns>An int.</returns>
        public int DeleteAll <T>(Expression <Func <T, bool> > where = null)
        {
            var ev = DialectProvider.ExpressionVisitor <T>();

            if (where != null)
            {
                ev.Where(where);
            }
            return(DeleteAll(ev));
        }
        public async Task <int> UpdateAllAsync <T, TKey>(T obj, Expression <Func <T, TKey> > onlyField, Expression <Func <T, bool> > where = null)
        {
            var ev = DialectProvider.ExpressionVisitor <T>();

            ev.Where(where);
            if (onlyField != null)
            {
                ev.Update(onlyField);
            }
            return(await UpdateAllAsync <T>(obj, ev));
        }
        /// <summary>
        /// Update all object of a given type
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj">New values</param>
        /// <param name="onlyField">Fields to update</param>
        /// <param name="where">Where clause</param>
        /// <returns></returns>
        public int UpdateAll <T>(object obj, Expression <Func <T, bool> > where = null, Expression <Func <T, object> > onlyField = null)
        {
            var ev = DialectProvider.ExpressionVisitor <T>();

            ev.Where(where);
            if (onlyField != null)
            {
                ev.Update(onlyField);
            }
            return(UpdateAll <T>(obj, ev));
        }
        /// <summary>
        /// Update all properties of object instance
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model">Object to update</param>
        /// <returns></returns>
        public int Update <T>(T model)
        {
            var cmd = DialectProvider.ToUpdateRowStatement(model, DialectProvider.ExpressionVisitor <T>());

            return(this.ExecuteScalar <int>(cmd));
        }
        /// <summary>
        ///    An OrmConnection method that counts the given database connection.
        /// </summary>
        /// <typeparam name="T">Generic type parameter.</typeparam>

        public long Count <T>()
        {
            return(Count(DialectProvider.ExpressionVisitor <T>()));
        }
        /// <summary>An OrmConnection method that selects.</summary>
        /// <typeparam name="T">Generic type parameter.</typeparam>
        /// <param name="predicate">The predicate.</param>
        /// <param name="buffered"></param>
        /// <param name="flags"></param>
        /// <returns>A List&lt;T&gt;</returns>
        public IEnumerable <T> Select <T>(Expression <Func <T, bool> > predicate, CommandFlags flags = CommandFlags.Buffered)
        {
            var ev = DialectProvider.ExpressionVisitor <T>();

            return(this.Query <T>(DialectProvider.ToSelectStatement(ev.Where(predicate), flags)));
        }
        /// <summary>
        ///    An OrmConnection method that counts the given database connection.
        /// </summary>
        /// <typeparam name="T">Generic type parameter.</typeparam>
        /// <param name="expression">The ev.</param>
        /// <returns>A long.</returns>
        public long Count <T>(Expression <Func <T, bool> > expression)
        {
            var ev = DialectProvider.ExpressionVisitor <T>();

            return(Count(ev.Where(expression)));
        }
 /// <summary>
 ///    An OrmConnection method that counts the given database connection.
 /// </summary>
 /// <typeparam name="T">Generic type parameter.</typeparam>
 /// <returns>A long.</returns>
 public async Task <long> CountAsync <T>()
 {
     return(await CountAsync(DialectProvider.ExpressionVisitor <T>()));
 }
 /// <summary>An OrmConnection method that selects.</summary>
 /// <typeparam name="T">Generic type parameter.</typeparam>
 /// <returns>A List&lt;T&gt;</returns>
 public async Task <IEnumerable <T> > SelectAsync <T>(CommandFlags flags = CommandFlags.Buffered)
 {
     return(await this.QueryAsync <T>(DialectProvider.ToSelectStatement(DialectProvider.ExpressionVisitor <T>(), flags)));
 }
 /// <summary>An OrmConnection method that deletes this object.</summary>
 /// <typeparam name="T">Generic type parameter.</typeparam>
 /// <param name="where"> The where.</param>
 /// <returns>An int.</returns>
 public async Task <int> DeleteAllAsync <T>(Func <SqlExpressionVisitor <T>, SqlExpressionVisitor <T> > where)
 {
     return(await DeleteAllAsync(where (DialectProvider.ExpressionVisitor <T>())));
 }
        /// <summary>An OrmConnection method that inserts an only.</summary>
        /// <typeparam name="T">Generic type parameter.</typeparam>
        /// <param name="obj">       The object.</param>
        /// <param name="onlyFields">The only fields.</param>
        public void InsertOnly <T>(T obj, Func <SqlExpressionVisitor <T>, SqlExpressionVisitor <T> > onlyFields) where T : new()
        {
            var ev = DialectProvider.ExpressionVisitor <T>();

            InsertOnly(obj, onlyFields(ev));
        }
        public async Task <int> UpdateAsync <T>(T model)
        {
            var cmd = DialectProvider.ToUpdateRowStatement(model, DialectProvider.ExpressionVisitor <T>());

            return(await this.ExecuteScalarAsync <int>(cmd));
        }
 /// <summary>An OrmConnection method that selects.</summary>
 /// <typeparam name="T">Generic type parameter.</typeparam>
 /// <param name="buffered"></param>
 /// <returns>A List&lt;T&gt;</returns>
 public IEnumerable <T> Select <T>(CommandFlags flags = CommandFlags.Buffered)
 {
     return(this.Query <T>(DialectProvider.ToSelectStatement(DialectProvider.ExpressionVisitor <T>(), flags)));
 }
        public async Task <long> CountAsync <T>(Func <SqlExpressionVisitor <T>, SqlExpressionVisitor <T> > expression)
        {
            var ev = DialectProvider.ExpressionVisitor <T>();

            return(await this.ExecuteScalarAsync <long>(DialectProvider.ToCountStatement(expression(ev))));
        }
 /// <summary>An OrmConnection method that deletes this object.</summary>
 /// <typeparam name="T">Generic type parameter.</typeparam>
 /// <param name="where"> The where.</param>
 /// <returns>An int.</returns>
 public int DeleteAll <T>(Func <SqlExpressionVisitor <T>, SqlExpressionVisitor <T> > where)
 {
     return(DeleteAll(where (DialectProvider.ExpressionVisitor <T>())));
 }
        /// <summary>
        ///    An OrmConnection method that counts the given database connection.
        /// </summary>
        /// <typeparam name="T">Generic type parameter.</typeparam>
        /// <param name="expression">The expression.</param>
        /// <returns>A long.</returns>
        public async Task <long> CountAsync <T>(Expression <Func <T, bool> > expression)
        {
            var ev = DialectProvider.ExpressionVisitor <T>();

            return(await CountAsync(ev.Where(expression)));
        }
        /// <summary>An OrmConnection method that first or default.</summary>
        /// <typeparam name="T">Generic type parameter.</typeparam>

        /// <param name="predicate">The predicate.</param>
        /// <returns>A T.</returns>
        public T FirstOrDefault <T>(Expression <Func <T, bool> > predicate)
        {
            var ev = DialectProvider.ExpressionVisitor <T>();

            return(Select(ev.Where(predicate).Limit(1)).FirstOrDefault());
        }
        public long Count <T>(Func <SqlExpressionVisitor <T>, SqlExpressionVisitor <T> > expression)
        {
            var ev = DialectProvider.ExpressionVisitor <T>();

            return(this.ExecuteScalar <long>(DialectProvider.ToCountStatement(expression(ev))));
        }