示例#1
0
        /// <summary>
        /// Conditionally add an implementation of the <see cref="ISimpleDataOrder"/> implementation. If condition returns true, clause is added. Otherwise, it is not.
        /// </summary>
        /// <param name="order">Simple data order to add to clause.</param>
        /// <param name="condition">Clause condition which determines if clause will be inserted. The parameter passed into this is the value parameter of this method. Returning true adds clause, false skips it.</param>
        /// <returns>Modified clause if condition was true. Otherwise, returns input clause.</returns>
        public Clause AddClause(ISimpleDataOrder order, Func <bool> condition)
        {
            bool conditionFailed = condition() == false || string.IsNullOrWhiteSpace(order.Query);

            if (conditionFailed)
            {
                return(this);
            }

            return(GetClone(order.Query, order.Parameters));
        }
示例#2
0
        private static IAliasedDataOrder CreateQuery(string tableName,
                                                     IEnumerable <KeyValuePair <string, object> > columns,
                                                     Clause whereCondition,
                                                     IEnumerable <string> outputParameters,
                                                     Func <IEnumerable <KeyValuePair <string, string> >, string, string> queryProducer,
                                                     IEnumerable <Func <string, IEnumerable <string>, IAliasedDataOrder> > outputClauseFunctions
                                                     )
        {
            var columnArray = columns.ToArray();

            var columnsWithParameterNames = new List <KeyValuePair <string, string> >();
            var parameterNamesWithValue   = new List <KeyValuePair <string, object> >();

            for (int i = 0; i < columnArray.Length; i++)
            {
                KeyValuePair <string, object> pair = columnArray[i];
                string parameterName = Clause.GenerateParameterName();
                columnsWithParameterNames.Add(new KeyValuePair <string, string>(pair.Key, parameterName));
                parameterNamesWithValue.Add(new KeyValuePair <string, object>(parameterName, pair.Value));
            }

            string outputClause = "";
            List <IAliasedDataOrder> outputDataOrders = new List <IAliasedDataOrder>();

            if (outputParameters.Any())
            {
                outputDataOrders.AddRange(outputClauseFunctions.Select(f => f(tableName, outputParameters)));

                if (outputDataOrders.Any())
                {
                    outputClause = "\r\nOUTPUT"
                                   + $"\r\n{string.Join(",\r\n", outputDataOrders.Select(dO => dO.Query))}";
                }
            }

            ISimpleDataOrder whereClause = whereCondition.Build();

            var parameters =
                Get.List <KeyValuePair <string, object> >(list => {
                list.AddRange(parameterNamesWithValue);
                list.AddRange(whereClause.Parameters);
            });

            string query = queryProducer(columnsWithParameterNames, outputClause);

            if (string.IsNullOrEmpty(whereClause.Query) == false)
            {
                query += "\r\nWHERE" + whereClause.Query;
            }

            return(new AliasedDataOrder(GenericQueryProvider.SurroundQueryWithTransaction(query), parameters, outputDataOrders.SelectMany(dO => dO.Aliases)));
        }
 /// <summary>
 /// Creates data order. Allows a previously created order's CommandType to be specified.
 /// </summary>
 /// <param name="order">Previously built data order.</param>
 /// <param name="commandType">The commandType of the Query.</param>
 public AliasedCommandTypeDataOrder(ISimpleDataOrder order, CommandType commandType) : this(order.Query, commandType, order.Parameters, new IAlias[0])
 {
 }
示例#4
0
 /// <summary>
 /// Create aliased data order. This allows you include aliases along with your data order.
 /// </summary>
 /// <param name="order">Previously built data order.</param>
 /// <param name="aliases">The aliases in use by Query.</param>
 public AliasedDataOrder(ISimpleDataOrder order, IEnumerable <IAlias> aliases) : this(order.Query, order.Parameters, aliases)
 {
 }
示例#5
0
 /// <summary>
 /// Create aliased data order. This allows you include aliases along with your data order.
 /// </summary>
 /// <param name="order">Previously built data order.</param>
 public AliasedDataOrder(ISimpleDataOrder order) : this(order.Query, order.Parameters, new IAlias[0])
 {
 }
示例#6
0
        /// <summary>
        /// Get query that can be used to copy all wanted fields into new records.
        /// </summary>
        /// <typeparam name="TModelAbstraction">The abstraction which contains metadata for the table.</typeparam>
        /// <typeparam name="TModelImplementation">The implementation of the abstraction to be used as an intermediary.</typeparam>
        /// <param name="order">The information for the query.</param>
        /// <param name="clauseCallback">The method that will produce the clause for the query.</param>
        /// <param name="wrapInTransaction">Whether to wrap in transaction or not.</param>
        /// <returns><see cref="IAliasedCommandTypeDataOrder"/> containing the query, parents, and aliases.</returns>
        public static IAliasedCommandTypeDataOrder GetRecordCopyQuery <TModelAbstraction, TModelImplementation>(RecordCopyOrder <TModelImplementation> order, Func <RecordCopyClauseCallbackOrder, Clause> clauseCallback, bool wrapInTransaction = true) where TModelImplementation : TModelAbstraction
        {
            // Ascertain types in order to use reflection.
            Type abstractionType    = typeof(TModelAbstraction);
            Type implementationType = typeof(TModelImplementation);

            // This dictionary gets the meta data of the abstract type. Missing some of these will cause an exception.
            Dictionary <Type, string> metaDataDictionary = MetaDataOperations.GetMetaDataNames(abstractionType);

            // Get table name from meta data.
            string tableName = metaDataDictionary
                               .First(dict => dict.Key == typeof(TableNameAttribute))
                               .Value;

            // Get id set for use in filtering clause.
            KeyValuePair <string, object>[] idSet =
                order
                .TransferKeys
                .Select((r, index) => new KeyValuePair <string, object>(Clause.GenerateParameterName(), r))
                .ToArray();

            // Produce a dictionary that has the values pulled in from the DefaultModel supplied through parameter.
            // Key => Name of field which should match property name.
            // Value => KeyValuePair where Key => ParameterName, Value => value of property.
            Dictionary <string, KeyValuePair <string, object> > defaultValues =
                new[] {
                metaDataDictionary[typeof(CreatorAttribute)],
                metaDataDictionary[typeof(DateCreatedAttribute)],
                order.ParentIdName,
            }
            .Concat(order.DefaultFieldsToCopy)
            .Where(field => field != metaDataDictionary[typeof(IdAttribute)] && field != metaDataDictionary[typeof(UpdatorAttribute)] && field != metaDataDictionary[typeof(DateUpdatedAttribute)])
            .Distinct()
            .ToDictionary(field => field, field => new KeyValuePair <string, object>(Clause.GenerateParameterName(), implementationType.GetProperty(field).GetValue(order.DefaultModel)));

            // Identify fields that should not be copied from record to record.
            // Use these fields to produce a list of fields not containing these fields.
            string[] unwantedFields =
                metaDataDictionary
                .Where(dict => dict.Key != typeof(TableNameAttribute))
                .Select(dict => dict.Value)
                .Concat(defaultValues.Select(value => value.Key))
                .Distinct()
                .ToArray();
            string[] fieldsToCopy = abstractionType.GetProperties().Where(prop => unwantedFields.Contains(prop.Name) == false).Select(prop => prop.Name).OrderBy(field => field).ToArray();

            // A collection of field names, with accompanying parameters are produced.
            Tuple <string, string>[] fieldParameterNameTupleCollection = defaultValues.Select(value => Tuple.Create(value.Key, value.Value.Key)).ToArray();

            // Here is a callback that can be used to produce the clause that filters the records to be copied.
            Clause tempTableClause = clauseCallback(new RecordCopyClauseCallbackOrder(idSet.Select(id => Tuple.Create(id.Key, id.Value)), fieldParameterNameTupleCollection));

            // Get the record copy query, assemble parameters, and return.
            ISimpleDataOrder transferQuery = Get.RecordCopyQuery(tableName, metaDataDictionary[typeof(IdAttribute)], tempTableClause, fieldParameterNameTupleCollection, fieldsToCopy);

            var parameters = transferQuery
                             .Parameters
                             .Concat(defaultValues.Select(value => value.Value))
                             .Concat(idSet)
                             .OrderBy(pair => pair.Key);

            string query =
                wrapInTransaction ?
                SurroundQueryWithTransaction(transferQuery.Query) :
                transferQuery.Query;

            return(new AliasedCommandTypeDataOrder(query, CommandType.Text, parameters));
        }
示例#7
0
 /// <summary>
 /// Add an implementation of the <see cref="ISimpleDataOrder"/> implementation. If condition returns true, clause is added. Otherwise, it is not.
 /// </summary>
 /// <param name="order">Simple data order to add to clause.</param>
 /// <returns>Modified clause if condition was true. Otherwise, returns input clause.</returns>
 public Clause AddClause(ISimpleDataOrder order) =>
 AddClause(order, () => true);