예제 #1
0
        protected void DefineForeignKeyNodes(string childForeignKeyPrefix, string childForeignKeyName, CodeProperty masterCodeProp, IList <PropertySelectorViewModel> list, string detailClassName, int currentNestedLevel)
        {
            CodeClass masterCodeClass               = masterCodeProp.Type.CodeType as CodeClass;
            string    masterCodePropName            = masterCodeProp.Name;
            List <SolutionCodeElement> primKeyProps = GetPrimaryKeyProperties(masterCodeClass);

            // SolutionCodeElement.CodeElementRef holds 'CodeProperty'
            // collect ColumnAttributes to define order
            if (primKeyProps.Count < 1)
            {
                // throw an exception here
                return;
            }


            //////////////////////////////////////////////////
            ///  The 1st case:
            ///  ---------
            ///  public class DetailType {
            ///
            ///     public int MasterRefId1 { get; set; }
            ///     public int MasterRefId2 { get; set; }
            ///
            ///     [ForeignKey("MasterRefId1")]
            ///     [ForeignKey("MasterRefId2")]
            ///     public MasterType MasterProp { get; set; }
            ///  }
            //////////////////////////////////////////////////
            foreach (CodeElement cea in masterCodeProp.Attributes)
            {
                string        foreignKeyName = "";
                CodeAttribute ca             = cea as CodeAttribute;
                if (ca.FullName.Contains("System.ComponentModel.DataAnnotations.Schema.ForeignKeyAttribute"))
                {
                    foreach (CodeElement chld in ca.Children)
                    {
                        if (chld is CodeAttributeArgument)
                        {
                            foreignKeyName = (chld as CodeAttributeArgument).Value;
                        }
                        foreignKeyName = foreignKeyName.Replace("\"", "");
                    }
                    foreach (ClassFiledSelectorViewModel itm in list)
                    {
                        if (foreignKeyName.Equals(itm.OriginalPropertyName))
                        {
                            PropertySelectorViewModel fk = null;
                            if (itm.ForeigKeyParentProperties == null)
                            {
                                itm.ForeigKeyParentProperties = new ObservableCollection <PropertySelectorViewModel>();
                            }
                            else
                            {
                                fk = itm.ForeigKeyPPByForeignKN(masterCodePropName);
                            }
                            if (fk == null)
                            {
                                fk = new PropertySelectorViewModel()
                                {
                                    ForeignKeyName = masterCodePropName
                                };
                                itm.IsForeignKeyField = true;
                                itm.ForeigKeyParentProperties.Add(fk);
                            }
                        }
                    }
                }
            }

            //////////////////////////////////////////////////
            ///  The 2nd case:
            ///  ---------
            ///  public class DetailType {
            ///
            ///     public int MasterRefId1 { get; set; }
            ///     public int MasterRefId2 { get; set; }
            ///  }
            ///  public class MasterType {
            ///     [ForeignKey("MasterRefId1")]
            ///     [ForeignKey("MasterRefId2")]
            ///     public ICollection<DetailType>  DetailProps { get; set; }
            ///  }
            //////////////////////////////////////////////////

            if (!string.IsNullOrEmpty(detailClassName))
            {
                foreach (CodeElement ce in masterCodeClass.Members)
                {
                    if (ce.Kind != vsCMElement.vsCMElementProperty)
                    {
                        continue;
                    }
                    CodeProperty loopCodeProp = ce as CodeProperty;
                    if (loopCodeProp.Access != vsCMAccess.vsCMAccessPublic)
                    {
                        continue;
                    }
                    if (loopCodeProp.Type == null)
                    {
                        continue;
                    }
                    if (loopCodeProp.Type.CodeType == null)
                    {
                        continue;
                    }
                    bool isNotMapped = false;
                    foreach (CodeElement cea in loopCodeProp.Attributes)
                    {
                        CodeAttribute ca = cea as CodeAttribute;
                        if (ca.FullName.Contains("System.ComponentModel.DataAnnotations.Schema.NotMappedAttribute"))
                        {
                            isNotMapped = true;
                            break;
                        }
                    }
                    if (isNotMapped)
                    {
                        continue;
                    }
                    CodeTypeRef ctRef = loopCodeProp.Type;
                    if (ctRef.TypeKind == vsCMTypeRef.vsCMTypeRefArray)
                    {
                        continue;
                    }
                    if (ctRef.TypeKind != vsCMTypeRef.vsCMTypeRefCodeType)
                    {
                        continue;
                    }
                    if (ctRef.CodeType.Kind != vsCMElement.vsCMElementInterface)
                    {
                        continue;
                    }
                    string className = ctRef.CodeType.FullName.Replace("System.Collections.Generic.ICollection<", "").Replace(">", "").Trim();
                    if (!detailClassName.Equals(className, StringComparison.OrdinalIgnoreCase))
                    {
                        continue;
                    }
                    // look for InversePropertyAttribute
                    string inversePropertyName = "";
                    foreach (CodeElement cea in loopCodeProp.Attributes)
                    {
                        CodeAttribute ca = cea as CodeAttribute;
                        if (ca.FullName.Contains("System.ComponentModel.DataAnnotations.Schema.InversePropertyAttribute"))
                        {
                            foreach (CodeElement chld in ca.Children)
                            {
                                if (chld is CodeAttributeArgument)
                                {
                                    inversePropertyName = (chld as CodeAttributeArgument).Value;
                                }
                                inversePropertyName = inversePropertyName.Replace("\"", "");
                            }
                        }
                    }

                    if (!string.IsNullOrEmpty(inversePropertyName))
                    {
                        if (!inversePropertyName.Equals(masterCodePropName, StringComparison.OrdinalIgnoreCase))
                        {
                            continue;
                        }
                    }

                    foreach (CodeElement cea in loopCodeProp.Attributes)
                    {
                        string        foreignKeyName = "";
                        CodeAttribute ca             = cea as CodeAttribute;
                        if (ca.FullName.Contains("System.ComponentModel.DataAnnotations.Schema.ForeignKeyAttribute"))
                        {
                            foreach (CodeElement chld in ca.Children)
                            {
                                if (chld is CodeAttributeArgument)
                                {
                                    foreignKeyName = (chld as CodeAttributeArgument).Value;
                                }
                                foreignKeyName = foreignKeyName.Replace("\"", "");
                            }
                            foreach (ClassFiledSelectorViewModel itm in list)
                            {
                                if (foreignKeyName.Equals(itm.OriginalPropertyName))
                                {
                                    PropertySelectorViewModel fk = null;
                                    if (itm.ForeigKeyParentProperties == null)
                                    {
                                        itm.ForeigKeyParentProperties = new ObservableCollection <PropertySelectorViewModel>();
                                    }
                                    else
                                    {
                                        fk = itm.ForeigKeyPPByForeignKN(masterCodePropName);
                                    }
                                    if (fk == null)
                                    {
                                        fk = new PropertySelectorViewModel()
                                        {
                                            ForeignKeyName = masterCodePropName
                                        };
                                        itm.ForeigKeyParentProperties.Add(fk);
                                        itm.IsForeignKeyField = true;
                                    }
                                }
                            }
                        }
                    }
                }
            }



            string[] names          = masterCodeProp.Type.AsFullName.Split(new char[] { '.' });
            string   masterTypeName = names[names.Length - 1];

            //masterCodePropName
            foreach (SolutionCodeElement primKeyProp in primKeyProps)
            {
                string primKeyPropName = primKeyProp.CodeElementName;
                if ("Id".Equals(primKeyPropName, StringComparison.OrdinalIgnoreCase))
                {
                    primKeyPropName = masterTypeName + primKeyPropName;
                }
                string fkNm = masterCodePropName + primKeyPropName;
                if (DefineForeigKeyNodeByForeigKeyFiledName(list, fkNm, masterCodePropName))
                {
                    continue;
                }
                fkNm = masterTypeName + primKeyPropName;
                if (DefineForeigKeyNodeByForeigKeyFiledName(list, fkNm, masterCodePropName))
                {
                    continue;
                }
                DefineForeigKeyNodeByForeigKeyFiledName(list, primKeyPropName, masterCodePropName);
            }
            // collect all foreign key fields for the given navigation property: masterCodePropName
            List <ClassFiledSelectorViewModel> fcflds = new List <ClassFiledSelectorViewModel>();

            foreach (ClassFiledSelectorViewModel itm in list)
            {
                if (itm.ForeigKeyParentProperties == null)
                {
                    continue;
                }
                if (itm.ForeigKeyPPByForeignKN(masterCodePropName) == null)
                {
                    continue;
                }
                fcflds.Add(itm);
            }
            if (fcflds.Count > 1)
            {
                fcflds.Sort((x, y) => x.FieldOrder - y.FieldOrder);
            }
            if (primKeyProps.Count > 1)
            {
                foreach (SolutionCodeElement sce in primKeyProps)
                {
                    CodeProperty cp = sce.CodeElementRef as CodeProperty;
                    foreach (CodeElement cea in cp.Attributes)
                    {
                        bool          OrderIsFound = false;
                        CodeAttribute ca           = cea as CodeAttribute;
                        if (ca.FullName.Contains("System.ComponentModel.DataAnnotations.Schema.ColumnAttribute"))
                        {
                            foreach (CodeElement chld in ca.Children)
                            {
                                if ("Order".Equals(chld.Name, System.StringComparison.OrdinalIgnoreCase))
                                {
                                    if (chld is CodeAttributeArgument)
                                    {
                                        int val;
                                        if (int.TryParse((chld as CodeAttributeArgument).Value, out val))
                                        {
                                            sce.Order    = val;
                                            OrderIsFound = true;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                        if (OrderIsFound)
                        {
                            break;
                        }
                    }
                }
                primKeyProps.Sort((x, y) => x.Order - y.Order);
            }
            int Count = primKeyProps.Count;

            if (Count > fcflds.Count)
            {
                Count = fcflds.Count;
            }
            for (int i = 0; i < Count; i++)
            {
                ClassFiledSelectorViewModel cfsvm = fcflds[i];
                PropertySelectorViewModel   psvm  = cfsvm.ForeigKeyPPByForeignKN(masterCodePropName);
                psvm.OriginalPropertyName = primKeyProps[i].CodeElementName;
                CodeProperty cp = primKeyProps[i].CodeElementRef as CodeProperty;
                psvm.TypeFullName       = cp.Type.AsFullName;
                psvm.UnderlyingTypeName = cp.Type.AsFullName;
                psvm.TypeIsNullable     = false;
                psvm.PocoName           = masterCodeClass.Name;
                psvm.PocoFullName       = masterCodeClass.FullName;
                if (currentNestedLevel + 1 <= this.MaxNestedLevel)
                {
                    psvm.ForeigKeyParentProperties = new ObservableCollection <PropertySelectorViewModel>();
                    DoPrepareClassFiledSelectorData(psvm.ChildForeignKeyPrefix, psvm.ForeignKeyName, psvm.ForeigKeyParentProperties, masterCodeClass as CodeElement, primKeyProps, currentNestedLevel);
                }
            }
        }
예제 #2
0
        protected void DoPrepareClassFiledSelectorData(string childForeignKeyPrefix, string childForeignKeyName, ObservableCollection <PropertySelectorViewModel> fkpp, CodeElement currentCodeElement, List <SolutionCodeElement> primKeyProps, int currentNestedLevel)
        {
            currentNestedLevel++;
            if (this.MaxNestedLevel < currentNestedLevel)
            {
                return;
            }
            if (fkpp == null)
            {
                return;
            }
            if (fkpp.Count > 0)
            {
                return;
            }
            if (currentCodeElement.Kind != vsCMElement.vsCMElementClass)
            {
                return;
            }
            CodeClass currentCodeClass = currentCodeElement as CodeClass;

            if (primKeyProps == null)
            {
                primKeyProps = GetPrimaryKeyProperties(currentCodeClass);
            }
            if (primKeyProps.Count < 1)
            {
                // throw an exception here
                return;
            }

            IList <CodeProperty> navigationProps = new List <CodeProperty>();
            IList <String>       fkeys           = new List <String>();
            int columnOrder = 0;

            foreach (CodeElement ce in currentCodeClass.Members)
            {
                fkeys.Clear();
                bool isNotMapped = false;
                //bool keyAttrib = false;
                bool   hasForeignAttrib         = false;
                string foreignKeyName           = "";
                bool   inversePropertyAttribute = false;
                bool   requiredAttribute        = false;
                // bool columnAttribute = false;
                int    columnAttributeOrder = -1;
                String typeName             = "";
                bool   typeIsNullable       = false;
                if (ce.Kind != vsCMElement.vsCMElementProperty)
                {
                    continue;
                }
                CodeProperty cp = ce as CodeProperty;
                if (cp.Access != vsCMAccess.vsCMAccessPublic)
                {
                    continue;
                }
                if (cp.Type == null)
                {
                    continue;
                }
                if (cp.Type.CodeType == null)
                {
                    continue;
                }
                foreach (CodeElement cea in cp.Attributes)
                {
                    CodeAttribute ca = cea as CodeAttribute;
                    if (ca.FullName.Contains("System.ComponentModel.DataAnnotations.Schema.NotMappedAttribute"))
                    {
                        isNotMapped = true;
                    }
                    //if (ca.FullName.Contains("System.ComponentModel.DataAnnotations.KeyAttribute"))
                    //{
                    //    keyAttrib = true;
                    //}
                    if (ca.FullName.Contains("System.ComponentModel.DataAnnotations.Schema.ForeignKeyAttribute"))
                    {
                        hasForeignAttrib = true;
                        foreach (CodeElement chld in ca.Children)
                        {
                            if (chld is CodeAttributeArgument)
                            {
                                foreignKeyName = (chld as CodeAttributeArgument).Value;
                            }
                            foreignKeyName = foreignKeyName.Replace("\"", "");
                            if (!string.IsNullOrEmpty(foreignKeyName))
                            {
                                if (!fkeys.Contains(foreignKeyName))
                                {
                                    fkeys.Add(foreignKeyName);
                                }
                            }
                        }
                    }
                    if (ca.FullName.Contains("System.ComponentModel.DataAnnotations.Schema.InversePropertyAttribute"))
                    {
                        inversePropertyAttribute = true;
                    }
                    if (ca.FullName.Contains("System.ComponentModel.DataAnnotations.RequiredAttribute"))
                    {
                        requiredAttribute = true;
                    }
                    if (ca.FullName.Contains("System.ComponentModel.DataAnnotations.Schema.ColumnAttribute"))
                    {
                        // columnAttribute = true;
                        foreach (CodeElement chld in ca.Children)
                        {
                            if ("Order".Equals(chld.Name, System.StringComparison.OrdinalIgnoreCase))
                            {
                                if (chld is CodeAttributeArgument)
                                {
                                    int val;
                                    if (int.TryParse((chld as CodeAttributeArgument).Value, out val))
                                    {
                                        columnAttributeOrder = val;
                                    }
                                }
                            }
                        }
                    }
                }
                if (inversePropertyAttribute || isNotMapped)
                {
                    continue;
                }

                CodeTypeRef ctf = cp.Type;
                // if CodeTypeRef.TypeKind = vsCMTypeRef.vsCMTypeRefArray the 'CodeTypeRef.ElementType' holds the type of the array Item
                // but in our case we will ignory Arrays
                if (ctf.TypeKind == vsCMTypeRef.vsCMTypeRefArray)
                {
                    continue;
                }
                if (ctf.TypeKind == vsCMTypeRef.vsCMTypeRefCodeType)
                {
                    // this is ForeignKey-navigation property so it must be saved for a while
                    if (cp.Type.CodeType.Kind == vsCMElement.vsCMElementClass)
                    {
                        navigationProps.Add(cp);
                        continue;
                    }
                    // ICollection<T> property: this is InverseProperty(...) so it must be ignored
                    if (cp.Type.CodeType.Kind == vsCMElement.vsCMElementInterface)
                    {
                        string fl = cp.Type.CodeType.FullName;
                        if (fl != null)
                        {
                            fl = "";
                        }
                        continue;
                    }
                    if (!ctf.AsFullName.StartsWith("System.Nullable"))
                    {
                        continue;
                    }
                    typeName       = ctf.AsFullName.Replace("System.Nullable", "").Replace("<", "").Replace(">", "").Trim();
                    typeIsNullable = true;
                }
                else
                {
                    typeName = ctf.AsFullName;
                }



                if (columnAttributeOrder < 0)
                {
                    columnAttributeOrder = columnOrder;
                }
                ClassFiledSelectorViewModel aProperty = new ClassFiledSelectorViewModel()
                {
                    OriginalPropertyName  = cp.Name,
                    ViewModelFieldName    = childForeignKeyPrefix + childForeignKeyName + cp.Name,
                    JsonPropertyFieldName = childForeignKeyPrefix + childForeignKeyName + cp.Name,
                    FieldOrder            = columnAttributeOrder,
                    IsForeignKeyField     = hasForeignAttrib,
                    ForeignKeyName        = childForeignKeyName,
                    ForeignKeyAlias       = childForeignKeyName,
                    ChildForeignKeyPrefix = childForeignKeyPrefix,
                    TypeFullName          = ctf.AsFullName,
                    UnderlyingTypeName    = typeName,
                    TypeIsNullable        = typeIsNullable,
                    UpdateDependent       = true,
                    UpdateNested          = true,
                    PocoName             = currentCodeClass.Name,
                    PocoFullName         = currentCodeClass.FullName,
                    HasRequiredAttribute = requiredAttribute
                };
                if (hasForeignAttrib)
                {
                    foreach (string fk in fkeys)
                    {
                        if (aProperty.ForeigKeyParentProperties == null)
                        {
                            aProperty.ForeigKeyParentProperties = new ObservableCollection <PropertySelectorViewModel>();
                        }
                        PropertySelectorViewModel fko = new PropertySelectorViewModel()
                        {
                            ForeignKeyName        = fk,
                            ChildForeignKeyPrefix = childForeignKeyPrefix + childForeignKeyName,
                            ForeignKeyAlias       = fk,
                            UpdateDependent       = true,
                            UpdateNested          = true,
                        };
                        aProperty.ForeigKeyParentProperties.Add(fko);
                    }
                }
                fkpp.Add(aProperty);
                columnOrder++;
            }

            foreach (SolutionCodeElement cp in primKeyProps)
            {
                string propNmae = cp.CodeElementName;
                foreach (ClassFiledSelectorViewModel itm in fkpp)
                {
                    if (propNmae.Equals(itm.OriginalPropertyName, StringComparison.OrdinalIgnoreCase))
                    {
                        itm.IsKeyField = true;
                        break;
                    }
                }
            }

            foreach (CodeProperty cp in navigationProps)
            {
                DefineForeignKeyNodes(childForeignKeyPrefix, childForeignKeyName, cp, fkpp, currentCodeClass.Name, currentNestedLevel);
            }

            OnPropertyChanged("ForeigKeyParentProperties");
        }