Beispiel #1
0
        private static Dictionary <RecordKeyCombo, List <DataRow> > GetManySideRowsDictionary(List <string> manySideJoinFields, DataTable manySideData)
        {
            var manySideRowsLookup = new Dictionary <RecordKeyCombo, List <DataRow> >(new RecordKeyComboComparer());

            foreach (DataRow row in manySideData.Rows.Cast <DataRow>())
            {
                var recordKeyCombo = RecordKeyCombo.GetRecordKeyComboFromDataRow(row, manySideJoinFields);

                if (manySideRowsLookup.ContainsKey(recordKeyCombo))
                {
                    manySideRowsLookup[recordKeyCombo].Add(row);
                }
                else
                {
                    manySideRowsLookup.Add(recordKeyCombo, new List <DataRow>()
                    {
                        row
                    });
                }
            }

            return(manySideRowsLookup);
        }
Beispiel #2
0
        public static EntityBatch Compare(OneToMany_OneWayDataMap map,
                                          DataTable sourceData, DuplicateRowBehavior sourceDataDuplicateRowBehavior,
                                          DataTable targetData, DuplicateRowBehavior targetDataDuplicateRowBehavior)
        {
            if (map == null)
            {
                throw new Exception("Data map can not be null.");
            }

            if (sourceData == null)
            {
                throw new Exception("Source-side data table can not be null.");
            }

            if (targetData == null)
            {
                throw new Exception("Target-side data table can not be null.");
            }

            if (map.EntityToUpdateDefinition.InsertsToExcludeFilter != null)
            {
                throw new Exception("Exclusion filter for inserts is not supported for one-to-many data maps.");
            }

            if (map.EntityToUpdateDefinition.UpdatesToExcludeFilter != null)
            {
                throw new Exception("Exclusion filter for updates is not supported for one-to-many data maps.");
            }

            if (map.EntityToUpdateDefinition.DeletionsToExcludeFilter != null)
            {
                throw new Exception("Exclusion filter for deletions is not supported for one-to-many data maps.");
            }

            if (map.SyncDirection == SyncDirection.SourceToTarget)
            {
                DataTableHelper.RemoveDuplicates(sourceData, map.JoinKeysCollection.JoinFields.Select(d => d.SourceJoinField).ToList(), sourceDataDuplicateRowBehavior);
            }
            else if (map.SyncDirection == SyncDirection.TargetToSource)
            {
                DataTableHelper.RemoveDuplicates(targetData, map.JoinKeysCollection.JoinFields.Select(d => d.TargetJoinField).ToList(), targetDataDuplicateRowBehavior);
            }
            else
            {
                throw new EnumValueNotImplementedException <SyncDirection>(map.SyncDirection);
            }

            //ValidateSyncFieldsExistInDataTables(map, sourceData, targetData);

            //ValidateDataOnlyFieldsExistInMap(map);

            DataTable     oneSideData       = null;
            List <string> oneSideJoinFields = null;

            DataTable     manySideData       = null;
            List <string> manySideJoinFields = null;

            var batch = new EntityBatch(map.EntityToUpdateDefinition);

            if (map.EntityToUpdateDefinition.SyncSide == SyncSide.Source)
            {
                if (map.SyncDirection == SyncDirection.SourceToTarget)
                {
                    throw new Exception(string.Format("{0}-side can not be updated for sync direction '{1}'.",
                                                      Enum.GetName(typeof(SyncSide), map.EntityToUpdateDefinition.SyncSide),
                                                      Enum.GetName(typeof(SyncDirection), map.SyncDirection)));
                }

                ValidateFieldsToTransposeExistInDataTable(targetData, map.ColumnNamesToTranspose);

                oneSideData       = targetData;
                oneSideJoinFields = map.JoinKeysCollection.JoinFields.Select(d => d.TargetJoinField).ToList();

                manySideData       = sourceData;
                manySideJoinFields = map.JoinKeysCollection.JoinFields.Select(d => d.SourceJoinField).ToList();
            }
            else if (map.EntityToUpdateDefinition.SyncSide == SyncSide.Target)
            {
                if (map.SyncDirection == SyncDirection.TargetToSource)
                {
                    throw new Exception(string.Format("{0}-side can not be updated for sync direction '{1}'.",
                                                      Enum.GetName(typeof(SyncSide), map.EntityToUpdateDefinition.SyncSide),
                                                      Enum.GetName(typeof(SyncDirection), map.SyncDirection)));
                }

                ValidateFieldsToTransposeExistInDataTable(sourceData, map.ColumnNamesToTranspose);

                oneSideData       = sourceData;
                oneSideJoinFields = map.JoinKeysCollection.JoinFields.Select(d => d.SourceJoinField).ToList();

                manySideData       = targetData;
                manySideJoinFields = map.JoinKeysCollection.JoinFields.Select(d => d.TargetJoinField).ToList();
            }
            else
            {
                throw new EnumValueNotImplementedException <SyncSide>(map.EntityToUpdateDefinition.SyncSide);
            }

            var customSetFieldsForDelete = map.CustomSetFields
                                           .Where(d => (d.AppliesTo.HasFlag(SyncOperation.Deletes) || d.AppliesTo.HasFlag(SyncOperation.All)));

            var dataOnlyFields = batch.EntityDefinition.DataOnlyFields.ToDictionary(d => d.FieldName, d => d, StringComparer.OrdinalIgnoreCase);

            var manySideRowsLookup = GetManySideRowsDictionary(manySideJoinFields, manySideData);

            foreach (var oneSideRow in oneSideData.Rows.Cast <DataRow>())
            {
                var oneSideRecordKeyCombo = RecordKeyCombo.GetRecordKeyComboFromDataRow(oneSideRow, oneSideJoinFields);

                List <DataRow> manySideFilteredRows = null;

                if (manySideRowsLookup.ContainsKey(oneSideRecordKeyCombo))
                {
                    manySideFilteredRows = manySideRowsLookup[oneSideRecordKeyCombo];
                }
                else
                {
                    manySideFilteredRows = new List <DataRow>();
                }

                foreach (var fieldToTranspose in map.ColumnNamesToTranspose)
                {
                    var transposeResult = map.TransposeMethod(manySideFilteredRows, oneSideRow, fieldToTranspose);

                    if (transposeResult == null)
                    {
                        continue;
                    }

                    var transposeDataOnlyValues = GetTransposeDataOnlyFieldValues(map.EntityToUpdateDefinition.TransposeDataOnlyFields, oneSideRow, manySideFilteredRows, fieldToTranspose);

                    EntityRecord entityRecord;

                    if (transposeResult is TransposeResult_AddRecord && batch.EntityDefinition.ApplyInserts)
                    {
                        entityRecord = AddInsertToBatch(map, batch, dataOnlyFields, oneSideRow, transposeResult, transposeDataOnlyValues);
                    }
                    else if (transposeResult is TransposeResult_UpdateRecord && batch.EntityDefinition.ApplyUpdates)
                    {
                        entityRecord = AddUpdateToBatch(map, batch, dataOnlyFields, oneSideRow, manySideFilteredRows, transposeResult, transposeDataOnlyValues);
                    }
                    else if (transposeResult is TransposeResult_DeleteRecord && batch.EntityDefinition.ApplyDeletions)
                    {
                        entityRecord = AddDeletionToBatch(map, batch, dataOnlyFields, oneSideRow, manySideFilteredRows, transposeResult, transposeDataOnlyValues);
                    }
                    else
                    {
                        throw new DerivedClassNotImplementedException <TransposeResult>(transposeResult);
                    }
                }
            }

            return(batch);
        }