/// <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)); }
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]) { }
/// <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) { }
/// <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]) { }
/// <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)); }
/// <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);