public static List <NavigationProperty> GetNavigationProperties <T>(this DbEntityEntry <T> entity, DbContext context) where T : class
        {
            List <System.Reflection.PropertyInfo> properties = new List <System.Reflection.PropertyInfo>();
            //Get the entity type
            Type entityType = entity.GetType();
            //Get the System.Data.Entity.Core.Metadata.Edm.EntityType
            //associated with the entity.
            MetadataWorkspace    workspace      = ((IObjectContextAdapter)context).ObjectContext.MetadataWorkspace;
            ObjectItemCollection itemCollection = (ObjectItemCollection)(workspace.GetItemCollection(DataSpace.OSpace));
            EntityType           etype          = itemCollection.OfType <EntityType>().Single(e => itemCollection.GetClrType(e) == typeof(T));

            return(etype.NavigationProperties.ToList());
        }
        /// <summary>
        /// Generates metadata for given item collection.
        /// Fetches CLR models from object item collection.
        /// </summary>
        /// <param name="metadataWorkspace">The metadata workspace.</param>
        /// <param name="itemCollection">The item collection.</param>
        /// <param name="objectItemCollection">The object item collection.</param>
        /// <param name="assembly">The assembly.</param>
        /// <param name="connectionString">The connection string.</param>
        /// <returns></returns>
        /// <exception cref="BeetleException">Cannot load mapping information.</exception>
        public static Metadata Generate(MetadataWorkspace metadataWorkspace, ItemCollection itemCollection,
                                        ObjectItemCollection objectItemCollection, Assembly assembly, string connectionString) {
            XDocument mappingXml = null;
            XNamespace mappingNs = null;
            try {
                var csResourceMatch = Regex.Match(connectionString, @"res:*/(.*?\.msl)");
                if (csResourceMatch.Success) {
                    var csResourceIndex = csResourceMatch.Value.LastIndexOf('/');
                    if (csResourceIndex >= 0) {
                        var csResource = csResourceMatch.Value.Substring(csResourceIndex + 1);
                        if (!string.IsNullOrEmpty(csResource)) {
                            using (var stream = assembly.GetManifestResourceStream(csResource)) {
                                if (stream != null) {
                                    using (var reader = new StreamReader(stream)) {
                                        mappingXml = XDocument.Load(reader);
                                        // ReSharper disable once PossibleNullReferenceException
                                        mappingNs = mappingXml.Root.GetDefaultNamespace();
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch {
                mappingXml = null;
            }

            var container = itemCollection.OfType<EntityContainer>().FirstOrDefault();
            // collect necessary entity information in one collection.
            var entityResources = new List<EntityResource>();
            foreach (var entityType in itemCollection.OfType<EntityType>().OrderBy(et => et.Name)) {
                var et = entityType;
                var entitySet = GetEntitySet(container, et);

                IEnumerable<KeyValuePair<string, string>> propertyMappings = null;
                XElement entityMap = null;
                if (mappingXml != null) {
                    entityMap = mappingXml
                        .Descendants(mappingNs.GetName("EntitySetMapping"))
                        .First(esm => esm.Attribute("Name").Value == entitySet.Name)
                        .Descendants(mappingNs.GetName("EntityTypeMapping"))
                        .First(mf => {
                            var typeName = mf.Attribute("TypeName").Value;
                            return typeName == et.FullName || typeName == string.Format("IsTypeOf({0})", et.FullName);
                        })
                        .Descendants(mappingNs.GetName("MappingFragment"))
                        .Single();
                    propertyMappings = entityMap.Descendants(mappingNs.GetName("ScalarProperty"))
                        .Select(sp => new KeyValuePair<string, string>(sp.Attribute("Name").Value, sp.Attribute("ColumnName").Value));
                }

                var complexProperties = et.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == et);
                Dictionary<EdmProperty, IEnumerable<ColumnMapping>> complexMappings = null;
                if (entityMap != null) {
                    complexMappings = new Dictionary<EdmProperty, IEnumerable<ColumnMapping>>();
                    foreach (var complexProperty in complexProperties) {
                        var complexMapping = entityMap
                            .Descendants(mappingNs.GetName("ComplexProperty"))
                            .First(cp => cp.Attribute("Name").Value == complexProperty.Name)
                            .Descendants(mappingNs.GetName("ScalarProperty"))
                            .Select(p => new ColumnMapping(p.Attribute("Name").Value, p.Attribute("ColumnName").Value));
                        complexMappings.Add(complexProperty, complexMapping);
                    }
                }

                var entityResource = new EntityResource {
                    Entity = et,
                    Type = et,
                    Name = et.Name,
                    EntitySet = entitySet,
                    SimpleProperties = et.Properties
                        .Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == et)
                        .ToDictionary(p => propertyMappings == null ? p.Name : propertyMappings.First(pm => pm.Key == p.Name).Value, p => p),
                    NavigationProperties = et.NavigationProperties.Where(np => np.DeclaringType == et),
                    ComplexProperties = complexMappings,
                    ClrType = objectItemCollection.GetClrType(objectItemCollection.OfType<EntityType>().First(x => x.Name == et.Name)),
                    TableName = entityMap == null ? et.Name : entityMap.Attribute("StoreEntitySet").Value
                };

                entityResources.Add(entityResource);
            }

            foreach (var complexType in itemCollection.OfType<ComplexType>().OrderBy(i => i.Name)) {
                var ct = complexType;
                var simpleProperties = ct.Properties
                    .Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == ct)
                    .ToDictionary(p => p.Name, p => p);
                var entityResource = new EntityResource {
                    Type = ct,
                    Name = ct.Name,
                    SimpleProperties = simpleProperties,
                    ClrType = objectItemCollection.GetClrType(objectItemCollection.OfType<ComplexType>().First(x => x.Name == ct.Name))
                };

                entityResources.Add(entityResource);
            }

            var enumResources = new List<EnumResource>();
            foreach (var enumType in itemCollection.OfType<EnumType>()) {
                var oSpaceEnumType = objectItemCollection.OfType<EnumType>().First(x => x.Name == enumType.Name);
                var enumClrType = objectItemCollection.GetClrType(oSpaceEnumType);
                enumResources.Add(new EnumResource { EnumType = enumType, ClrType = enumClrType });
            }

            return Mapping(entityResources, enumResources, itemCollection, container);
        }
Beispiel #3
0
        public static Metadata Generate(MetadataWorkspace metadataWorkspace, ItemCollection itemCollection,
                                        ObjectItemCollection objectItemCollection, Assembly assembly, string modelName = null)
        {
            var container = itemCollection.OfType <EntityContainer>().First();

            XDocument  mappingXml = null;
            XNamespace mappingNs  = null;

            try {
                if (modelName == null)
                {
                    var schemaSource = container.MetadataProperties["SchemaSource"].Value.ToString();
                    modelName = Regex.Match(schemaSource, @"res://.*/(.*?)\.csdl").Groups[1].Value;
                }

                using (var stream = assembly.GetManifestResourceStream(modelName + ".msl")) {
                    if (stream != null)
                    {
                        using (var reader = new StreamReader(stream)) {
                            mappingXml = XDocument.Load(reader);
                            // ReSharper disable once PossibleNullReferenceException
                            mappingNs = mappingXml.Root.GetDefaultNamespace();
                        }
                    }
                }
            }
            catch {
                mappingXml = null;
            }

            // collect necessary entity information in one collection.
            var entityResources = new List <EntityResource>();

            foreach (var entityType in itemCollection.OfType <EFEntityType>().OrderBy(et => et.Name))
            {
                var et        = entityType;
                var entitySet = GetEntitySet(container, et);

                IEnumerable <KeyValuePair <string, string> > propertyMappings = null;
                XElement entityMap = null;
                if (mappingXml != null)
                {
                    entityMap = mappingXml
                                .Descendants(mappingNs.GetName("EntitySetMapping"))
                                .First(esm => esm.Attribute("Name")?.Value == entitySet.Name)
                                .Descendants(mappingNs.GetName("EntityTypeMapping"))
                                .First(mf => {
                        var typeName = mf.Attribute("TypeName")?.Value;
                        return(typeName == et.FullName || typeName == $"IsTypeOf({et.FullName})");
                    })
                                .Descendants(mappingNs.GetName("MappingFragment"))
                                .Single();

                    propertyMappings = entityMap.Descendants(mappingNs.GetName("ScalarProperty"))
                                       .Select(sp => new KeyValuePair <string, string>(
                                                   sp.Attribute("Name")?.Value, sp.Attribute("ColumnName")?.Value)
                                               );
                }

                var complexProperties = et.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == et);
                Dictionary <EdmProperty, IEnumerable <ColumnMapping> > complexMappings = null;
                if (entityMap != null)
                {
                    complexMappings = new Dictionary <EdmProperty, IEnumerable <ColumnMapping> >();
                    foreach (var complexProperty in complexProperties)
                    {
                        var complexMapping = entityMap
                                             .Descendants(mappingNs.GetName("ComplexProperty"))
                                             .First(cp => cp.Attribute("Name")?.Value == complexProperty.Name)
                                             .Descendants(mappingNs.GetName("ScalarProperty"))
                                             .Select(p => new ColumnMapping(p.Attribute("Name")?.Value, p.Attribute("ColumnName")?.Value));
                        complexMappings.Add(complexProperty, complexMapping);
                    }
                }

                var entityResource = new EntityResource {
                    Entity           = et,
                    Type             = et,
                    Name             = et.Name,
                    EntitySet        = entitySet,
                    SimpleProperties = et.Properties
                                       .Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == et)
                                       .ToDictionary(p => propertyMappings == null ? p.Name : propertyMappings.First(pm => pm.Key == p.Name).Value, p => p),
                    NavigationProperties = et.NavigationProperties.Where(np => np.DeclaringType == et),
                    ComplexProperties    = complexMappings,
                    ClrType   = objectItemCollection.GetClrType(objectItemCollection.OfType <EFEntityType>().First(x => x.Name == et.Name)),
                    TableName = entityMap?.Attribute("StoreEntitySet")?.Value ?? et.Name
                };

                entityResources.Add(entityResource);
            }

            foreach (var complexType in itemCollection.OfType <ComplexType>().OrderBy(i => i.Name))
            {
                var ct = complexType;
                var simpleProperties = ct.Properties
                                       .Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == ct)
                                       .ToDictionary(p => p.Name, p => p);
                var entityResource = new EntityResource {
                    Type             = ct,
                    Name             = ct.Name,
                    SimpleProperties = simpleProperties,
                    ClrType          = objectItemCollection.GetClrType(objectItemCollection.OfType <ComplexType>().First(x => x.Name == ct.Name))
                };

                entityResources.Add(entityResource);
            }

            var enumResources = new List <EnumResource>();

            foreach (var enumType in itemCollection.OfType <EFEnumType>())
            {
                var oSpaceEnumType = objectItemCollection.OfType <EFEnumType>().First(x => x.Name == enumType.Name);
                var enumClrType    = objectItemCollection.GetClrType(oSpaceEnumType);
                enumResources.Add(new EnumResource {
                    EnumType = enumType, ClrType = enumClrType
                });
            }

            return(Mapping(entityResources, enumResources, itemCollection, container));
        }