Beispiel #1
0
        public JoinTableQueryPart(QueryIdentifier targetTable,
                                  QueryIdentifier sourceTable,
                                  QueryIdentifier joinAlias,
                                  Type targetTargetTableType,
                                  ColumnInfo targetColumn,
                                  ColumnInfo sourceColumn,
                                  IEnumerable <ColumnInfo> columns,
                                  DbPropertyInfoCache targetProperty,
                                  JoinMode joinAs)
        {
            _joinAs         = joinAs;
            TargetTable     = targetTable;
            SourceTable     = sourceTable;
            Alias           = joinAlias;
            TargetTableType = targetTargetTableType;
            Columns         = columns;

            TargetColumn   = targetColumn;
            SourceColumn   = sourceColumn;
            DependingJoins = new List <JoinTableQueryPart>();

            var joinInfos = new JoinParseInfo();

            joinInfos.TargetProperty   = targetProperty;
            joinInfos.Columns          = Columns;
            joinInfos.Alias            = Alias;
            joinInfos.SourceColumnName = SourceColumn;
            joinInfos.TargetColumnName = TargetColumn;

            joinInfos.SourceTable     = SourceTable;
            joinInfos.TargetTableType = targetTargetTableType;
            JoinParseInfo             = joinInfos;
        }
        private void CreateJoinMapping(
            JoinParseInfo joinTableQueryPart,
            EagarDataRecord[] readers,
            Type entityType,
            QueryProcessingRecordsContext context)
        {
            var parentedReaders = new List <EagarDataRecord>();
            var property        = joinTableQueryPart.TargetProperty;

            var sourceColumn = joinTableQueryPart.TargetColumnName;
            var targetColumn = joinTableQueryPart.SourceColumnName;

            if (sourceColumn == null)
            {
                throw new InvalidOperationException();
            }
            if (targetColumn == null)
            {
                throw new InvalidOperationException();
            }

            var fields        = joinTableQueryPart.Columns.ToArray();
            var fieldsOfChild = fields
                                .Select((item, index) => item.ColumnIdentifier())
                                .ToArray();

            var columnMapping             = new Dictionary <string, int>();
            var sourceColumnsIndexMapping = context.Columns.ToArray().Select((item, index) => new
            {
                item,
                index
            }).ToDictionary(e => e.item, e => e.index);

            foreach (var fieldOfChild in fieldsOfChild)
            {
                var child         = fieldOfChild;
                var indexOfSource =
                    sourceColumnsIndexMapping
                    .FirstOrDefault(e => e.Key.ColumnIdentifier().Equals(child));
                if (columnMapping.ContainsKey(indexOfSource.Key.NaturalName))
                {
                    throw new InvalidOperationException($"Column name collision detected. Column '{indexOfSource.Key.NaturalName}'")
                          {
                              Data =
                              {
                                  { "Columns", sourceColumnsIndexMapping },
                                  { "Field",   indexOfSource             },
                              }
                          };
                }

                columnMapping.Add(indexOfSource.Key.NaturalName, indexOfSource.Value);
            }

            var groupBy = columnMapping[columnMapping.FirstOrDefault().Key];
            //TODO might not be the PrimaryKey of the foreign table

            var readerGroups = readers
                               .GroupBy(e => e[groupBy])
                               .Select(e => e.First())
                               .ToArray();

            foreach (var readerGroup in readerGroups)
            {
                var naturalReader = new EagarDataRecord(columnMapping.Keys.ToArray(),
                                                        new ArrayList(columnMapping.Values.Select(f => readerGroup[f]).ToArray()));

                parentedReaders.Add(naturalReader);
            }

            Mappings.Add(new RelationMapping()
            {
                TargetColumns = joinTableQueryPart.Columns,
                SourceColumns = context.Columns
                                .Where(e => e.Alias.Equals(joinTableQueryPart.SourceTable))
                                .ToArray(),
                Records      = parentedReaders.ToArray(),
                SourceColumn = sourceColumn,
                TargetColumn = targetColumn,
                TargetName   = property.PropertyName,
                TargetType   = entityType,
                SourceAlias  = joinTableQueryPart.Alias,
                TargetAlias  = joinTableQueryPart.SourceTable
            });

            if (readerGroups.Any())
            {
                foreach (var subJoinTableQueryPart in joinTableQueryPart.DependingJoins)
                {
                    CreateJoinMapping(subJoinTableQueryPart,
                                      readers,
                                      subJoinTableQueryPart.TargetTableType,
                                      context);
                }
            }

            foreach (var eagarDataRecord in readers)
            {
                foreach (var columnInfo in joinTableQueryPart.Columns)
                {
                    //eagarDataRecord.Remove(columnInfo.ColumnIdentifier());
                    eagarDataRecord.Remove(columnInfo.ColumnIdentifier().TrimAlias());
                }
            }

            context.Columns = context.Columns
                              .Except(joinTableQueryPart.Columns)
                              .ToArray();
        }
 public RelationProcessor(JoinParseInfo joinTableQueryPart)
 {
     _joinTableQueryPart = joinTableQueryPart;
     Mappings            = new List <RelationMapping>();
 }