Esempio n. 1
0
        private Tuple <MetadataWorkspace, SchemaData> LoadEdmx(string path)
        {
            try
            {
                string   spath   = Path.GetFullPath(path);
                XElement runtime = XElement.Load(path).Elements().First(e => e.Name.LocalName == "Runtime");

                XElement csdlSchema = runtime.Elements().First(e => e.Name.LocalName == "ConceptualModels")
                                      .Elements().First(e => e.Name.LocalName == "Schema")
                                      .Elements().First(e => e.Name.LocalName == "EntityContainer")
                ;
                string entityName = csdlSchema.Attributes().First(e => e.Name.LocalName == "Name").Value;

                EdmItemCollection edmCollection;
                XElement          csdl = runtime.Elements().First(e => e.Name.LocalName == "ConceptualModels")
                                         .Elements().First(e => e.Name.LocalName == "Schema");

                using (XmlReader reader = csdl.CreateReader())
                {
                    edmCollection = new EdmItemCollection(new[] { reader });
                }

                StoreItemCollection storeCollection;
                XElement            ssdl = runtime.Elements().First(e => e.Name.LocalName == "StorageModels")
                                           .Elements().First(e => e.Name.LocalName == "Schema");
                using (XmlReader reader = ssdl.CreateReader())
                {
                    storeCollection = new StoreItemCollection(new[] { reader });
                }

                SchemaData schema = new SchemaData()
                {
                    Name = entityName
                };
                foreach (XNode nod in ssdl.Nodes())
                {
                    if (nod.NodeType == XmlNodeType.Element)
                    {
                        XElement nodEle = (XElement)nod;
                        if (nodEle.Name.LocalName == "EntityType")
                        {
                            CodeGen.EntityType entityType = new CodeGen.EntityType()
                            {
                                Name = nodEle.Attribute("Name").Value
                            };
                            if (entityType.Name.StartsWith("VwCustomers"))
                            {
                                entityType.Name = entityType.Name + "";
                            }
                            List <string> primaryKeyList = new List <string>();
                            foreach (XNode member in ((XElement)nod).Nodes())
                            {
                                if (member.NodeType == XmlNodeType.Element)
                                {
                                    XElement nodMember = (XElement)member;
                                    if (nodMember.Name.LocalName == "Property")
                                    {
                                        Property property = new Property()
                                        {
                                            IsNullable = true
                                        };
                                        property.Name = nodMember.Attribute("Name").Value ?? "";
                                        property.Type = nodMember.Attribute("Type").Value ?? "";
                                        if (nodMember.Attribute("MaxLength") != null)
                                        {
                                            property.MaxLength = int.Parse(nodMember.Attribute("MaxLength").Value);
                                        }
                                        if (nodMember.Attribute("Nullable") != null)
                                        {
                                            property.IsNullable = bool.Parse(nodMember.Attribute("Nullable").Value);
                                        }
                                        if (nodMember.Attribute("Precision") != null)
                                        {
                                            property.Precision = int.Parse(nodMember.Attribute("Precision").Value);
                                        }
                                        if (nodMember.Attribute("Scale") != null)
                                        {
                                            property.Scale = int.Parse(nodMember.Attribute("Scale").Value);
                                        }
                                        if ((nodMember.Attribute("StoreGeneratedPattern") != null) && (nodMember.Attribute("StoreGeneratedPattern").Equals("Identity")))
                                        {
                                            property.IsIdentity = true;
                                        }
                                        entityType.Properties.Add(property.Name, property);
                                    }
                                    else if (nodMember.Name.LocalName == "Key")
                                    {
                                        foreach (XNode nodKey in ((XElement)nodMember).Nodes())
                                        {
                                            XElement eleKey = (XElement)nodKey;
                                            string   sKey   = eleKey.Attribute("Name").Value ?? "";
                                            primaryKeyList.Add(sKey);
                                        }
                                    }
                                }
                            }
                            foreach (string primaryKeyName in primaryKeyList)
                            {
                                if (entityType.Properties.ContainsKey(primaryKeyName))
                                {
                                    entityType.Properties[primaryKeyName].IsKey = true;
                                    entityType.PrimaryKeys.Add(entityType.Properties[primaryKeyName]);
                                }
                            }
                            schema.Add(entityType.Name, entityType);
                        }
                    }
                }

                StorageMappingItemCollection mappingCollection;
                XElement msl = runtime.Elements().First(e => e.Name.LocalName == "Mappings")
                               .Elements().First(e => e.Name.LocalName == "Mapping");
                using (XmlReader reader = msl.CreateReader())
                {
                    mappingCollection = new StorageMappingItemCollection(
                        edmCollection,
                        storeCollection,
                        new[] { reader });
                }
                MetadataWorkspace mdRet = new MetadataWorkspace(() => edmCollection, () => storeCollection, () => mappingCollection);
                //Resolve foriegn keys using MetadataWorkspace
                var relationshipEndMembers = new Dictionary <RelationshipEndMember, Tuple <System.Data.Entity.Core.Metadata.Edm.EntityType, NavigationProperty> >();
                var entitySets             = mdRet.GetItems <EntityContainer>(DataSpace.CSpace).First().BaseEntitySets;

                foreach (var s in entitySets)
                {
                    try
                    {
                        if ((s.BuiltInTypeKind == BuiltInTypeKind.EntitySet) || (s.BuiltInTypeKind == BuiltInTypeKind.EntityType) || (s.BuiltInTypeKind == BuiltInTypeKind.EntitySetBase))
                        {
                            if (s.Name.StartsWith("VwCustomers"))
                            {
                                var Name = (s.Name + " ").Trim();
                            }
                            var navProperties = ((System.Data.Entity.Core.Metadata.Edm.EntityType)s.ElementType).DeclaredNavigationProperties;
                            if ((navProperties.Count > 0) && (schema.ContainsKey(s.Name)))
                            {
                                foreach (var navProperty in navProperties)
                                {
                                    //Thank you http://stackoverflow.com/questions/5365708/ef4-get-the-linked-column-names-from-navigationproperty-of-an-edmx
                                    AssociationType association          = mdRet.GetItems <AssociationType>(DataSpace.CSpace).Single(a => a.Name == navProperty.RelationshipType.Name);
                                    string          fromEntity           = association.ReferentialConstraints[0].FromRole.Name;
                                    string          fromEntityField      = association.ReferentialConstraints[0].FromProperties[0].Name;
                                    string          toEntity             = association.ReferentialConstraints[0].ToRole.Name;
                                    string          toEntityField        = association.ReferentialConstraints[0].ToProperties[0].Name;
                                    string          toEntityColumnName   = toEntityField.Replace("Id", "").Replace("UID", "");
                                    string          fromEntityColumnName = fromEntityField.Replace("Id", "").Replace("UID", "");
                                    var             ns = new XmlNamespaceManager(new NameTable());
                                    ns.AddNamespace("edmx", "http://schemas.microsoft.com/ado/2009/11/edm");
                                    var r = entitySets.First(a => a.Name == navProperty.RelationshipType.Name);
                                    //Figure out the real entity names based off the end keys
                                    var ends = ((System.Data.Entity.Core.Metadata.Edm.AssociationSet)r).AssociationSetEnds;
                                    if (ends != null)
                                    {
                                        var fromEnd = ends.First(e => e.Name == fromEntity);
                                        if (fromEnd != null)
                                        {
                                            fromEntity = fromEnd.EntitySet.Name;
                                        }
                                        var toEnd = ends.First(e => e.Name == toEntity);
                                        if (toEnd != null)
                                        {
                                            toEntity = toEnd.EntitySet.Name;
                                        }
                                    }

                                    var newRel = new Relationship()
                                    {
                                        Name        = navProperty.RelationshipType.Name, FromTableName = fromEntity, FromFieldName = fromEntityField, ToFieldName = toEntityField,
                                        ToTableName = toEntity, ToColumnName = toEntityColumnName,
                                        Type        = navProperty.FromEndMember.RelationshipMultiplicity.ToString() + " to " + navProperty.ToEndMember.RelationshipMultiplicity.ToString()
                                    };
                                    schema[s.Name].Relationships.Add(newRel);
                                    var fieldToMarkRelation = (s.Name.Equals(newRel.FromTableName) ? newRel.FromFieldName : newRel.ToFieldName);
                                    if (schema[s.Name].Properties.ContainsKey(fieldToMarkRelation))
                                    {
                                        schema[s.Name].Properties[fieldToMarkRelation].RelatedTo.Add(newRel);
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception exE)
                    {
                        Console.WriteLine(exE.Message);
                        throw;
                    }
                }

                //Go through Edmx and get the type of object of each entity.  Important because we do different things when we mess with views
                XElement xeele = runtime.Elements().First(e => e.Name.LocalName == "StorageModels")
                                 .Elements().First(e => e.Name.LocalName == "Schema")
                                 .Elements().First(e => e.Name.LocalName == "EntityContainer");
                foreach (var item in xeele.Nodes())
                {
                    XElement ele = (XElement)item;
                    if (ele.Attribute("Name") == null)
                    {
                        Console.WriteLine("Error: could not read Name Attribute");
                    }
                    var name       = ele.Attribute("Name").Value;
                    var schemaName = "";
                    if (ele.Attribute("Schema") != null)
                    {
                        schemaName = ele.Attribute("Schema").Value;
                    }
                    XNamespace w          = "http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator";
                    var        entityType = ele.Attribute(w + "Type");
                    if (entityType != null)
                    {
                        if (schema.ContainsKey(name))
                        {
                            schema[name].Type   = entityType.Value.ToSingular();
                            schema[name].Schema = schemaName;
                        }
                    }
                }

                return(new Tuple <MetadataWorkspace, SchemaData>(mdRet, schema));
            }
            catch (Exception ex)
            {
                Console.Write(ex.Message);
                throw;
            }
        }
Esempio n. 2
0
        public static SchemaData GenerateSchemaObjects(string entityName, string ConnectionString)
        {
            try
            {
                SchemaData schema = new SchemaData()
                {
                    Name = entityName
                };
                using (SqlConnection connection = new SqlConnection(ConnectionString))
                {
                    if (connection.State == ConnectionState.Closed)
                    {
                        connection.Open();
                    }

                    SqlCommand cmdCompat11 = new SqlCommand("DECLARE @sql NVARCHAR(1000) = 'ALTER DATABASE ' + DB_NAME() + ' SET COMPATIBILITY_LEVEL = 110'; EXECUTE sp_executesql @sql", connection);
                    cmdCompat11.CommandType = CommandType.Text;
                    cmdCompat11.ExecuteNonQuery();
                    using (SqlCommand cmd = new SqlCommand(FKSQL, connection))
                    {
                        cmd.CommandType = CommandType.Text;

                        var ds      = new DataSet();
                        var adapter = new SqlDataAdapter(cmd);
                        adapter.Fill(ds);
                        var                  tableColumnData   = ds.Tables[0];
                        var                  CurrentEntityName = "";
                        EntityType           entityType        = null;
                        PrimaryKeyProperties primaryKeyList    = null;
                        foreach (DataRow row in tableColumnData.Rows)
                        {
                            var tableName = row["TABLENAME"].ToString();
                            if (CurrentEntityName != tableName)
                            {
                                if (CurrentEntityName.Length > 0)
                                {
                                    //Temporal views are handled below
                                    if ((!entityType.HasPrimaryKeys() && (!entityType.IsTemporalView) && (entityType.TemporalType != "HISTORY_TABLE")))
                                    {
                                        Console.WriteLine("Warning... '" + CurrentEntityName + "' no primary keys.. adding all as primary keys");
                                        int order = 0;
                                        foreach (var prop in entityType.Properties.Values)
                                        {
                                            order++;
                                            prop.IsKey    = true;
                                            prop.KeyOrder = order;
                                            entityType.PrimaryKeys.Add(prop);
                                        }
                                    }
                                    schema.Add(CurrentEntityName, entityType);
                                }
                                entityType = new EntityType()
                                {
                                    Name             = tableName
                                    , Type           = row["OBJECT_TYPE"].ToString()
                                    , Schema         = row["SCHEMANAME"].ToString()
                                    , IsTemporalView = ((tableName.EndsWith("TemporalView")) && (row["OBJECT_TYPE"].ToString() == "VIEW"))
                                    , TemporalType   = (row["TEMPORAL_TYPE_DESC"] == DBNull.Value ? "" : row["TEMPORAL_TYPE_DESC"].ToString())
                                };
                                primaryKeyList         = new PrimaryKeyProperties(entityType);
                                entityType.PrimaryKeys = primaryKeyList;
                                CurrentEntityName      = tableName;
                            }
                            Property property = new Property()
                            {
                                IsNullable = (bool)row["IS_NULLABLE"]
                            };
                            property.Name       = (row["COLUMNNAME"] == DBNull.Value ? "" : row["COLUMNNAME"].ToString());
                            property.MaxLength  = (int)(row["CHARACTER_MAXIMUM_LENGTH"] == DBNull.Value ? 0 : row["CHARACTER_MAXIMUM_LENGTH"]);
                            property.Precision  = (int)(row["NUMERIC_PRECISION"] == DBNull.Value ? 0 : Convert.ToInt32(row["NUMERIC_PRECISION"]));
                            property.Scale      = (int)(row["NUMERIC_SCALE"] == DBNull.Value ? 0 : Convert.ToInt32(row["NUMERIC_SCALE"]));
                            property.IsIdentity = (bool)(row["IS_IDENTITY"] == DBNull.Value ? false : row["IS_IDENTITY"]);
                            property.IsKey      = (bool)(row["PRIMARY_KEY_ORDER"] == DBNull.Value ? false : true);
                            property.KeyOrder   = (int)(row["PRIMARY_KEY_ORDER"] == DBNull.Value ? 0 : Convert.ToInt32(row["PRIMARY_KEY_ORDER"]));
                            if ((entityType.IsTemporalView) && ((property.Name == "SysEndTime") || (property.Name == "SysStartTime")))
                            {
                                property.IsKey    = true;
                                property.KeyOrder = ((property.Name == "SysStartTime") ? 1 : 2);
                            }
                            property.Type = (row["DATA_TYPE"] == DBNull.Value ? "" : row["DATA_TYPE"].ToString());
                            if (property.IsKey)
                            {
                                entityType.PrimaryKeys.Add(property);
                            }
                            entityType.Properties.Add(property.Name, property);
                        }
                        if (CurrentEntityName.Length > 0)
                        {
                            //Temporal views are handled abolve
                            if ((!entityType.HasPrimaryKeys() && (!entityType.IsTemporalView) && (entityType.TemporalType != "HISTORY_TABLE")))
                            {
                                Console.Write("Warning... '" + CurrentEntityName + "' no primary keys.. adding all as primary keys");
                                int order = 0;
                                foreach (var prop in entityType.Properties.Values)
                                {
                                    order++;
                                    prop.IsKey    = true;
                                    prop.KeyOrder = order;
                                    entityType.PrimaryKeys.Add(prop);
                                }
                            }
                            schema.Add(CurrentEntityName, entityType);
                        }
                        var tableFKeyData = ds.Tables[1];
                        foreach (DataRow row in tableFKeyData.Rows)
                        {
                            var tableName = row["EntityTable"].ToString();

                            string fromEntity           = (row["EntityTable"] == DBNull.Value ? "" : row["EntityTable"].ToString());
                            string fromEntityField      = (row["EntityColumn"] == DBNull.Value ? "" : row["EntityColumn"].ToString());
                            string toEntity             = (row["RelatedTable"] == DBNull.Value ? "" : row["RelatedTable"].ToString());
                            string toEntityField        = (row["RelatedColumn"] == DBNull.Value ? "" : row["RelatedColumn"].ToString());
                            string toEntityColumnName   = toEntityField.AsFormattedName();
                            string fromEntityColumnName = fromEntityField.AsFormattedName();
                            string multiplicity         = (row["Multiplicity"] == DBNull.Value ? "" : row["Multiplicity"].ToString());
                            var    newRel = new Relationship()
                            {
                                Name           = row["FK_Name"] == DBNull.Value ? "" : row["FK_Name"].ToString(),
                                FromTableName  = fromEntity,
                                FromFieldName  = fromEntityField,
                                FromColumnName = fromEntityColumnName,
                                ToFieldName    = toEntityField,
                                ToTableName    = toEntity,
                                ToColumnName   = toEntityColumnName,
                                Type           = multiplicity
                            };

                            schema[tableName].Relationships.Add(newRel);
                            var fieldToMarkRelation = (tableName.Equals(newRel.FromTableName) ? newRel.FromFieldName : newRel.ToFieldName);
                            if (schema[tableName].Properties.ContainsKey(fieldToMarkRelation))
                            {
                                schema[tableName].Properties[fieldToMarkRelation].RelatedTo.Add(newRel);
                            }
                        }
                    }

                    if (schema.ContainsKey("sysdiagrams"))
                    {
                        schema.Entities.Remove("sysdiagrams");
                    }
                    if (schema.ContainsKey("DeploymentMetadata"))
                    {
                        schema.Entities.Remove("DeploymentMetadata");
                    }

                    //REMOVE TEMPORAL TABLES
                    foreach (var t in schema.Keys.Where(k => k.EndsWith("Temporal", StringComparison.OrdinalIgnoreCase)).ToArray())
                    {
                        schema.Entities.Remove(t);
                    }
                    foreach (var t in schema.Keys.Where(k => k.ToLower().Contains("sysdiagram")).ToArray())
                    {
                        schema.Entities.Remove(t);
                    }
                    foreach (var t in schema.Keys.Where(k => k.Contains("TemporalHistoryFor")).ToArray())
                    {
                        schema.Entities.Remove(t);
                    }
                    //REMOVE Redgate tables
                    foreach (var t in schema.Keys.Where(k => k.EndsWith("DeploymentMetadata", StringComparison.OrdinalIgnoreCase)).ToArray())
                    {
                        schema.Entities.Remove(t);
                    }
                    var temporal = schema.Keys.Where(k => k.EndsWith("_Archive", StringComparison.OrdinalIgnoreCase)).ToArray();
                    foreach (var t in temporal)
                    {
                        schema.Entities.Remove(t);
                    }

                    SqlCommand cmdCompat13 = new SqlCommand("DECLARE @sql NVARCHAR(1000) = 'ALTER DATABASE ' + DB_NAME() + ' SET COMPATIBILITY_LEVEL = 130'; EXECUTE sp_executesql @sql", connection);
                    cmdCompat13.CommandType = CommandType.Text;
                    cmdCompat13.ExecuteNonQuery();

                    return(schema);
                }
            }
            catch (Exception)
            {
                throw;
            }
        }