public SelectQuery <TPoco> Join(string forginColumnName, [ValueProvider(nameof(JoinMode))] JoinMode joinAs = null) { var path = PropertyPath <TPoco> .Get(ContainerObject.AccessLayer.Config, forginColumnName) .Where(e => !typeof(IDbCollection).IsAssignableFrom(e.DeclaringType)) .Select(e => { var dbClassInfoCache = ContainerObject.AccessLayer.GetClassInfo(e.DeclaringType); if (dbClassInfoCache.Propertys.ContainsKey(e.Name)) { return(new KeyValuePair <DbClassInfoCache, DbPropertyInfoCache>(dbClassInfoCache, dbClassInfoCache.Propertys[e.Name])); } else { throw new InvalidOperationException($"The expected property '{e.Name}' was not found.") { Data = { { "Class", dbClassInfoCache } } }; } }) .ToArray(); return(JoinOn(this, path, joinAs)); }
public SelectQuery <TPoco> Join(string forginColumnName, [ValueProvider(nameof(JoinMode))] JoinMode joinAs = null) { var path = PropertyPath <TPoco> .Get(ContainerObject.AccessLayer.Config, forginColumnName) .Where(e => !typeof(IDbCollection).IsAssignableFrom(e.DeclaringType)) .Select(e => { var dbClassInfoCache = ContainerObject.AccessLayer.GetClassInfo(e.DeclaringType); return(new KeyValuePair <DbClassInfoCache, DbPropertyInfoCache>(dbClassInfoCache, dbClassInfoCache.Propertys[e.Name])); }) .ToArray(); return(JoinOn(path, joinAs)); }
internal static SelectQuery <TPoco> JoinOn( IQueryBuilder builder, KeyValuePair <DbClassInfoCache, DbPropertyInfoCache>[] path, JoinMode joinAs = null, Func <ConditionalEvalQuery <TPoco>, ConditionalEvalQuery <TPoco> > joinCondition = null) { joinAs = joinAs ?? JoinMode.Default; IQueryBuilder target = builder; var targetAlias = target.ContainerObject .SearchLast <ISelectableQueryPart>(e => !(e is JoinTableQueryPart)) .Alias; var parentJoinPart = builder.ContainerObject.Joins; foreach (var keyValuePair in path) { var targetTable = target.ContainerObject.Search(targetAlias); var pathOfJoin = target.ContainerObject.GetPathOf(targetAlias) + "." + keyValuePair.Value.PropertyName; var parentAlias = target.ContainerObject .CreateTableAlias(pathOfJoin); var joinExists = parentJoinPart.FirstOrDefault(e => e.Alias.Equals(parentAlias)); if (joinExists != null) { parentJoinPart = joinExists.DependingJoins; targetAlias = parentAlias; continue; } Type referenceType; if (keyValuePair.Value.CheckForListInterface()) { referenceType = keyValuePair.Value.PropertyType.GetElementType(); if (referenceType == null) { referenceType = keyValuePair.Value.PropertyType.GetGenericArguments().FirstOrDefault(); } } else { referenceType = keyValuePair.Value.PropertyType; } var referencedTypeCache = target.ContainerObject.AccessLayer.GetClassInfo(referenceType); var targetAliasOfJoin = new QueryIdentifier { QueryIdType = QueryIdentifier.QueryIdTypes.Table, Value = referencedTypeCache.TableName }; ColumnInfo onSourceTableKey; ColumnInfo selfPrimaryKey; var referenceColumn = keyValuePair.Value.ForginKeyAttribute?.Attribute; if (referenceColumn == null) { throw new InvalidOperationException("There is no known reference from table " + $"'{keyValuePair.Key.Type}' " + "to table " + $"'{referenceType}'." + "Use a ForeignKeyDeclarationAttribute to connect both"); } var forginColumns = DbAccessLayer.GetSelectableColumnsOf(referencedTypeCache) .Select(e => new ColumnInfo(e, parentAlias, target.ContainerObject)) .ToList(); selfPrimaryKey = targetTable.Columns.FirstOrDefault(e => e.IsEquivalentTo(referenceColumn.ForeignKey)); onSourceTableKey = forginColumns.FirstOrDefault(e => e.IsEquivalentTo(referenceColumn.ReferenceKey)); var joinTableQueryPart = new JoinTableQueryPart( targetAliasOfJoin, targetAlias, parentAlias, keyValuePair.Key.Type, onSourceTableKey, selfPrimaryKey, forginColumns, keyValuePair.Value, joinAs); parentJoinPart.Add(joinTableQueryPart.JoinParseInfo); parentJoinPart = joinTableQueryPart.JoinParseInfo.DependingJoins; target.ContainerObject.SearchLast <ISelectQueryPart>().AddJoin(joinTableQueryPart); target = target.Add(joinTableQueryPart); targetAlias = parentAlias; } if (joinCondition != null) { var lastJoin = target.ContainerObject.SearchLast <JoinTableQueryPart>(); var condition = new ConditionStatementQueryPart(); var tempSelect = new ConditionalEvalQuery <TPoco>(target.Add(condition)); joinCondition(tempSelect); lastJoin.Condition = condition; } return(new SelectQuery <TPoco>(target)); }