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>(); }