Ejemplo n.º 1
0
        public void AddMember(string memberExpression)
        {
            //if this is a native datamember, just add a SelectMember
            if (DataType.IsMapped(memberExpression))
            {
                DataMember dmember = DataType[memberExpression];

                //this is a native member of this dataType
                SelectMember sm = new SelectMember(dmember, dmember.Member.Expression.Replace('.', '_'));
                Members.Add(sm);

                //finish iteration here
                return;
            }

            //see if this is a dataMember from a base type
            foreach (DataType parent in DataType.BaseDataTypes.Skip(1))
            {
                if (!parent.IsMapped(memberExpression))
                {
                    continue;
                }

                //if this is a native datamember, just add a SelectMember
                DataMember dmember = parent[memberExpression];

                //create join for child-parent relationship
                SelectJoin join = Joins.Where(j => j.Type == parent && j.Alias == parent.Name + "_base").SingleOrDefault();

                if (join == null)
                {
                    join          = new SelectJoin();
                    join.JoinType = SelectJoinType.Inner;
                    join.Type     = parent;
                    join.Alias    = parent.Name + "_base";

                    var childPK = DataType.PrimaryKey.ToList();
                    var joinPK  = join.Type.PrimaryKey.ToList();

                    for (int y = 0; y < joinPK.Count; y++)
                    {
                        //DataMember pk in join.Type.PrimaryKey
                        var filter = new Filters.MemberCompareFilter()
                        {
                            Member                   = childPK[y],
                            MemberToCompare          = joinPK[y],
                            MemberToCompareTypeAlias = join.Alias,
                        };

                        join.On.Add(filter);
                    }

                    Joins.Add(join);
                }

                //this is a native member of this dataType
                SelectMember sm = new SelectMember(dmember, dmember.Member.Expression.Replace('.', '_'));
                join.Members.Add(sm);

                //finish iteration here
                return;
            }


            //if the expression was not found as a single datamember, split it in nested members
            List <System.Reflection.MemberInfo> nestedMemberInfos = MemberExpression.GetMemberInfos(DataType.InnerType, memberExpression).ToList();

            //check every part of the expression
            for (int i = 0; i < nestedMemberInfos.Count; i++)
            {
                System.Reflection.MemberInfo memberInfo = nestedMemberInfos[i];
                bool   isTheFirstOne     = i == 0;
                bool   isTheLastOne      = i == nestedMemberInfos.Count - 1;
                string currentExpression = string.Empty;

                for (int y = 0; y <= i; y++)
                {
                    currentExpression += '.' + nestedMemberInfos[y].Name;
                }

                currentExpression = currentExpression.Trim('.');

                //if this is a dataMember from a base type, create join for that relationship
                foreach (DataType parent in DataType.BaseDataTypes)
                {
                    DataType referencingDataType = isTheFirstOne ? parent : MemberExpression.GetReturnType(nestedMemberInfos[i - 1]);

                    //if this is not a native or inherited DataMember, so we must detect the nested members and create the respective joins
                    if (!isTheLastOne && DataType.IsMapped(MemberExpression.GetReturnType(memberInfo)))
                    {
                        DataType foreignDataType    = MemberExpression.GetReturnType(memberInfo);
                        bool     foreignKeyIsMapped = true;

                        foreach (DataMember foreignKey in foreignDataType.PrimaryKey)
                        {
                            DataMember localKey = referencingDataType.DataMembers.Where(m => m.Member.Expression == memberInfo.Name + "." + foreignKey.Member).SingleOrDefault();

                            if (localKey == null)
                            {
                                foreignKeyIsMapped = false;
                            }
                        }

                        if (foreignKeyIsMapped)
                        {
                            SelectJoin foreignJoin = Joins.Where(j => j.Type == foreignDataType && j.Alias == currentExpression.Replace('.', '_')).SingleOrDefault();

                            if (foreignJoin == null)
                            {
                                foreignJoin          = new SelectJoin();
                                foreignJoin.JoinType = SelectJoinType.Left;
                                foreignJoin.Type     = foreignDataType;
                                foreignJoin.Alias    = currentExpression.Replace('.', '_');

                                string previousJoinAlias = string.Empty;

                                if (isTheFirstOne && parent != DataType)
                                {
                                    previousJoinAlias = parent.Name + "_base";
                                }
                                else
                                {
                                    for (int y = 0; y <= i - 1; y++)
                                    {
                                        previousJoinAlias += '.' + nestedMemberInfos[y].Name;
                                    }

                                    previousJoinAlias = previousJoinAlias.Trim('.');
                                }

                                foreach (DataMember foreignKey in foreignDataType.PrimaryKey)
                                {
                                    DataMember localKey = referencingDataType.DataMembers.Where(m => m.Member.Expression == memberInfo.Name + "." + foreignKey.Member).SingleOrDefault();

                                    var filter = new Filters.MemberCompareFilter()
                                    {
                                        Member                   = localKey,
                                        MemberToCompare          = foreignKey,
                                        TypeAlias                = previousJoinAlias,
                                        MemberToCompareTypeAlias = foreignJoin.Alias,
                                    };

                                    foreignJoin.On.Add(filter);
                                }

                                Joins.Add(foreignJoin);
                            }

                            break;
                        }
                    }

                    if (!isTheFirstOne && isTheLastOne)
                    {
                        DataMember   dmember     = referencingDataType[memberInfo.Name];
                        SelectJoin   foreignJoin = Joins.Where(j => j.Type == referencingDataType && j.Alias == currentExpression.Replace("." + memberInfo.Name, string.Empty).Replace('.', '_')).SingleOrDefault();
                        SelectMember sm          = new SelectMember(dmember, currentExpression.Replace('.', '_'));
                        foreignJoin.Members.Add(sm);

                        break;
                    }
                }
            }
        }