/// <summary> /// The ORM type object from property info, the property type for parent relationships, a generic list's object for child relationships /// </summary> /// <param name="pi"></param> /// <returns></returns> public static Type GetParent(PropertyInfo pi) { if (typeof(IEnumerable).IsAssignableFrom(pi.PropertyType)) { Type baseType = pi.PropertyType; ORMChildJoinHint hint = pi.GetJoinHint(); if (hint != null && hint.ChildType != null) { return(hint.ChildType); } else { do { Type[] types = baseType.GetGenericArguments(); if (types.Length > 0) { return(types[0]); } }while ((baseType = baseType.BaseType) != null); } } else { return(pi.PropertyType); } return(null); }
public static ORMChildJoinHint GetJoinHint(this PropertyInfo pi) { if (!PropertyInfoExtensions._JoinHints.ContainsKey(pi)) { PropertyInfoExtensions._JoinHints.TryAdd(pi, null); Attribute[] customAttributes = Attribute.GetCustomAttributes(pi); int num = 0; while (num < (int)customAttributes.Length) { Attribute attr = customAttributes[num]; if (!(attr is ORMChildJoinHint)) { num++; } else { PropertyInfoExtensions._JoinHints[pi] = (ORMChildJoinHint)attr; break; } } } ORMChildJoinHint item = PropertyInfoExtensions._JoinHints[pi]; return(item); }
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; } } }