Exemple #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));
        }
Exemple #2
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="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, bool wrapInTransaction = true) where TModelImplementation : TModelAbstraction
        {
            Type abstractionType = typeof(TModelAbstraction);
            Dictionary <Type, string> metaDataDictionary = MetaDataOperations.GetMetaDataNames(abstractionType);
            string primaryKeyFieldName = metaDataDictionary
                                         .First(dict => dict.Key == typeof(IdAttribute))
                                         .Value;

            // In this case, the clause will filter out where the ParentId is the same as the current record, and then try to match any of the keys being tried for.
            Func <RecordCopyClauseCallbackOrder, Clause> clauseCallback = (rcccOrder) =>
                                                                          Clause.New()
                                                                          .AddClause($"{order.ParentIdName} <> {rcccOrder.FieldParameterNameTupleCollection.First(tuple => tuple.Item1 == order.ParentIdName).Item2}")
                                                                          .AddClause($"{primaryKeyFieldName} IN ({string.Join(",", rcccOrder.Keys.Select(r => $"\r\n   {r.Item1}"))}\r\n)")
            ;

            return(GetRecordCopyQuery <TModelAbstraction, TModelImplementation>(order, clauseCallback, wrapInTransaction));
        }