/// <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);
        }
Example #3
0
        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;
                }
            }
        }