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); }
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)); }