/// <summary>
        ///     Adds a LEFT JOIN to the Statement
        /// </summary>
        /// <typeparam name="TLeft">The type of the left.</typeparam>
        /// <typeparam name="TRight">The type of the right.</typeparam>
        /// <typeparam name="TAggregation">The type of the aggregation.</typeparam>
        /// <param name="query">The query.</param>
        /// <param name="mode">The mode.</param>
        /// <returns></returns>
        public static ElementProducer <TAggregation> Join <TLeft, TRight, TAggregation>(this ElementProducer <TLeft> query,
                                                                                        string mode = null)
        {
            if (mode == null)
            {
                mode = "";
            }

            var accessLayer = query.ContainerObject.AccessLayer;
            var sourcePK    = typeof(TLeft).GetFK(typeof(TRight), query.ContainerObject.AccessLayer.Config);

            if (sourcePK == null)
            {
                throw new ArgumentNullException("No Fk for this Constalation found");
            }
            var targetPK = typeof(TRight).GetPK(query.ContainerObject.AccessLayer.Config);

            if (targetPK == null)
            {
                throw new ArgumentNullException("No pk for this Constalation found");
            }
            var targetTable = accessLayer.GetClassInfo(typeof(TRight)).TableName;
            var sourceTable = accessLayer.GetClassInfo(typeof(TLeft)).TableName;

            return
                (new ElementProducer <TAggregation>(
                     query.QueryText("{4} JOIN {0} ON {0}.{1} = {3}.{2}", targetTable, targetPK, sourcePK, sourceTable, mode),
                     query.CurrentIdentifier));
        }
 /// <summary>
 ///     Creates an TSQL OrderBy statment
 /// </summary>
 /// <typeparam name="TPoco">The type of the poco.</typeparam>
 /// <typeparam name="TE">The type of the e.</typeparam>
 /// <param name="query">The query.</param>
 /// <param name="columnName">Name of the column.</param>
 /// <param name="desc">if set to <c>true</c> [desc].</param>
 /// <returns></returns>
 public static ConditionalQuery <TPoco> OrderByDesc <TPoco, TE>(this ElementProducer <TPoco> query,
                                                                Expression <Func <TPoco, TE> > columnName, bool desc = false)
 {
     return(new ConditionalQuery <TPoco>(query.QueryText("ORDER BY {0} DESC", columnName.GetPropertyInfoFromLamdba()),
                                         new CondtionBuilderState(query.CurrentIdentifier)));
 }
 /// <summary>
 ///     Creates an TSQL OrderBy statment
 /// </summary>
 /// <typeparam name="TPoco">The type of the poco.</typeparam>
 /// <param name="query">The query.</param>
 /// <param name="over">The over.</param>
 /// <returns></returns>
 public static ConditionalQuery <TPoco> OrderByDesc <TPoco>(this ElementProducer <TPoco> query, string over)
 {
     return(new ConditionalQuery <TPoco>(query.QueryText("ORDER BY {0} DESC", over),
                                         new CondtionBuilderState(query.CurrentIdentifier)));
 }
 /// <summary>
 ///     Append an RowNumberOrder part
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="query">The query.</param>
 /// <param name="over">The over.</param>
 /// <param name="desc">if set to <c>true</c> [desc].</param>
 /// <returns></returns>
 public static ElementProducer <T> RowNumberOrder <T>(this ElementProducer <T> query, string over, bool desc = false)
 {
     return(query.QueryText("ROW_NUMBER() OVER (ORDER BY {0} {1})", over, desc ? "DESC" : "ASC"));
 }
 /// <summary>
 ///     Append an AS part
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="query">The query.</param>
 /// <param name="alias">The alias.</param>
 /// <returns></returns>
 public static ElementProducer <T> As <T>(this ElementProducer <T> query, string alias)
 {
     return(query.QueryText("AS " + alias));
 }
 /// <summary>
 ///     Creates an TSQL Apply statement
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="query">The query.</param>
 /// <param name="mode">The mode.</param>
 /// <param name="innerText">The inner text.</param>
 /// <returns></returns>
 public static ElementProducer <T> Apply <T>(this ElementProducer <T> query,
                                             ApplyMode mode,
                                             Func <RootQuery, IQueryBuilder> innerText)
 {
     return(new ElementProducer <T>(new RootQuery(query.QueryText(mode.ApplyType)).InBracket(innerText), query.CurrentIdentifier));
 }
 /// <summary>
 ///     Creates a FOR XML statement that uses the name of the given type to allow the .net XML Serilizer to read the output
 /// </summary>
 /// <typeparam name="TPoco">The type of the poco.</typeparam>
 /// <param name="query">The query.</param>
 /// <param name="target">The target.</param>
 /// <returns></returns>
 public static ElementProducer <string> ForXml <TPoco>(this ElementProducer <TPoco> query, Type target)
 {
     return(new ElementProducer <string>(query.QueryText("FOR XML PATH('{0}'),ROOT('ArrayOf{0}'), TYPE", target.Name),
                                         query.CurrentIdentifier));
 }