private void EnsureChainJoins(List <PropertyInfo> pis, ORMSelect q) { SQFromTable t = (SQFromTable)Query.From.GetByAlias(q.FocalType.Name); if (pis.Count > 1) { string previousAlias = q.FocalType.Name; SchemaTable previousTable = _Schema.GetSchemaForType(q.FocalType); string currChain = pis[0].Name; for (int i = 1; i < pis.Count; i++) { PropertyInfo prevPi = pis[i - 1]; PropertyInfo pi = pis[i]; // TODO: use foreign key hints somehow currChain += "." + pi.Name; string joinAlias = GetJoinAlias(currChain, q); SchemaTable nextTable = _Schema.GetSchemaForType(pi.ReflectedType); if (Query.From.GetByAlias(joinAlias) == null) { SQJoin newJoin = new SQJoin() { Table = new SQAliasableObject(nextTable.Table.Name, joinAlias), JoinType = SQJoinTypes.Left }; t.Append(newJoin); if (typeof(IEnumerable).IsAssignableFrom(prevPi.PropertyType) && pi.ReflectedType != prevPi.PropertyType) { // join to a child ORMChildJoinHint hint = prevPi.GetJoinHint(); if (hint != null) { newJoin.Predicate = new SQCondition(previousAlias + "." + previousTable.Table.GetPrimaryKey().Name, SQRelationOperators.Equal, joinAlias + "." + nextTable.GetColumnByName(nextTable.GetFKeyByName(hint.FKeyPropertyName).Storage).Column.Name); } } else { // join to a parent newJoin.Predicate = new SQCondition(previousAlias + "." + previousTable.GetColumnByName(previousTable.GetFKeyByName(prevPi.Name).Storage).Column.Name, SQRelationOperators.Equal, joinAlias + "." + nextTable.Table.GetPrimaryKey().Name); } } previousAlias = joinAlias; previousTable = nextTable; } } }
public virtual string Write(SQJoin join) { StringBuilder sb = new StringBuilder(); while (join != null) { sb.AppendLine(string.Format("\r\n\t{0}JOIN {1}{2} ON\r\n", join.JoinType != SQJoinTypes.Inner ? join.JoinType.ToString().ToUpper() + " " : "", Write(join.Table.Actual), string.IsNullOrEmpty(join.Table.Alias) ? "" : " AS " + join.Table.Alias)); sb.AppendLine(Write(join.Predicate)); join = join.Join; } return(sb.ToString()); }