Пример #1
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));
        }
Пример #2
0
        /// <summary>
        /// Produces a query to delete a record from a table.
        /// </summary>
        /// <param name="id">The id which should be deleted.</param>
        /// <param name="tableName">The name of the table which will be operated on.</param>
        /// <param name="idPropertyName">The name of the id field.</param>
        /// <returns><see cref="IAliasedCommandTypeDataOrder"/> containing the query, parents, and aliases.</returns>
        public static IAliasedCommandTypeDataOrder DeleteSingleId(int id, string tableName, string idPropertyName)
        {
            Clause whereClause = Clause.New().AddClause($"@id{Get.SafeGuid()}", id, Clause.EqualStatementCallback(idPropertyName));

            return(new AliasedCommandTypeDataOrder(Get.DeleteQuery(tableName, whereClause), CommandType.Text));
        }
Пример #3
0
 /// <summary>
 /// Add previous built clause to this clause.
 /// </summary>
 /// <param name="clause">Previously built clause.</param>
 /// <returns>Modified clause.</returns>
 public Clause AddClause(Clause clause) =>
 AddClause(clause, () => true);