Example #1
0
        private void TableBaseComplexMigration(SourceTable tbl, Converter[] converter, List<SourceColumn> mappedColumns, List<SourceColumn> referringCols, Join[] additional_joins)
        {
            if (additional_joins != null
                && additional_joins.Length > 0
                && additional_joins.All(j => referringCols
                    .Select(c => c.DestinationProperty.Single())
                    .OfType<ObjectReferenceProperty>()
                    .Any(orp => j.JoinTableName == _dst.GetTableName(orp.RelationEnd.Parent.GetOtherEnd(orp.RelationEnd).Type.Module.SchemaName, orp.RelationEnd.Parent.GetOtherEnd(orp.RelationEnd).Type.TableName))))
            {
                throw new InvalidOperationException("Unmapped additional joins found");
            }

            // could automatically create needed indices
            var all_joins = new Dictionary<SourceColumn, Join>();
            var root_joins = referringCols
                .GroupBy(k => k.DestinationProperty.Single())
                .SelectMany(referenceGroup => CreateReferenceJoin(referenceGroup, all_joins))
                .ToArray();

            // Add manual joins
            IEnumerable<Join> joins;
            if (additional_joins != null)
            {
                joins = root_joins.Union(additional_joins);
            }
            else
            {
                joins = root_joins;
            }

            var srcColumns = mappedColumns
                                .Where(c => c.References == null)
                                .Union(
                                    referringCols
                                        .GroupBy(k => k.DestinationProperty.Single()) // referring columns cannot be mapped remotely
                                        .Select(g => g.First(p => p.References.References == null))
                                ).ToList();
            var srcColumnNames = srcColumns.Select(c =>
            {
                var orp = c.DestinationProperty.FirstOrDefault() as ObjectReferenceProperty;
                if (c.References != null)
                {
                    return new ProjectionColumn("ID", all_joins[c], System.Data.DbType.Int32, c.DestinationProperty.Single().Name);
                }
                else if (c.References == null
                    && orp != null)
                {
                    if (additional_joins != null
                        && additional_joins.Count(i => i.JoinTableName == _dst.GetTableName(orp.RelationEnd.Parent.GetOtherEnd(orp.RelationEnd).Type.Module.SchemaName, orp.RelationEnd.Parent.GetOtherEnd(orp.RelationEnd).Type.TableName)) > 0)
                    {
                        return new ProjectionColumn(
                            "ID",
                            additional_joins.Single(j => j.JoinTableName == _dst.GetTableName(orp.RelationEnd.Parent.GetOtherEnd(orp.RelationEnd).Type.Module.SchemaName, orp.RelationEnd.Parent.GetOtherEnd(orp.RelationEnd).Type.TableName)),
                            System.Data.DbType.Int32,
                            orp.Name);
                    }
                    else if (converter.Any(cnv => cnv.Column.Name == c.Name))
                    {
                        return new ProjectionColumn(c.Name, ColumnRef.PrimaryTable, c.DestinationProperty.Single().Name);
                    }
                    else
                    {
                        throw new InvalidOperationException(string.Format("No join found for {0}", c));
                    }
                }
                else
                {
                    return new ProjectionColumn(c.Name, ColumnRef.PrimaryTable, (System.Data.DbType)c.DbType, null);
                }
            }).ToList();

            var dstColumnNames = GetDestinationColumnNames(tbl, srcColumns);
            long processedRows;

            using (var srcReader = _src.ReadJoin(_src.GetTableName(tbl.StagingDatabase.Schema, tbl.Name), srcColumnNames, joins))
            using (var translator = new Translator(tbl, srcReader, srcColumns, converter))
            {
                _dst.WriteTableData(_dst.GetTableName(tbl.DestinationObjectClass.Module.SchemaName, tbl.DestinationObjectClass.TableName), translator, dstColumnNames);
                processedRows = translator.ProcessedRows;
            }

            // count rows in original table, joins should not add or remove rows
            WriteLog(
                tbl.Name, _src.CountRows(_src.GetTableName(tbl.StagingDatabase.Schema, tbl.Name)),
                tbl.DestinationObjectClass.TableName, processedRows);
        }