/// <summary> /// Constrcutor to create an instance of DefaultObjectMappingItemCollection. /// To start with we will create a Schema under which maps will be created. /// </summary> /// <param name="edmCollection"></param> /// <param name="objectCollection"></param> public DefaultObjectMappingItemCollection(EdmItemCollection edmCollection, ObjectItemCollection objectCollection) : base(DataSpace.OCSpace) { EntityUtil.CheckArgumentNull(edmCollection, "edmCollection"); EntityUtil.CheckArgumentNull(objectCollection, "objectCollection"); this.m_edmCollection = edmCollection; this.m_objectCollection = objectCollection; LoadPrimitiveMaps(); }
public void ExplicitLoadFromAssembly_checks_only_given_assembly_for_views() { var mockCache = new Mock<IViewAssemblyCache>(); var objectItemCollection = new ObjectItemCollection(mockCache.Object); objectItemCollection.ExplicitLoadFromAssembly( typeof(object).Assembly, new EdmItemCollection(Enumerable.Empty<XmlReader>()), null); mockCache.Verify(m => m.CheckAssembly(typeof(object).Assembly, false), Times.Once()); }
public void ImplicitLoadAllReferencedAssemblies_does_not_check_assembly_for_views_if_assembly_filtered() { var mockCache = new Mock<IViewAssemblyCache>(); var objectItemCollection = new ObjectItemCollection(mockCache.Object); objectItemCollection.ImplicitLoadAllReferencedAssemblies( typeof(object).Assembly, new EdmItemCollection(Enumerable.Empty<XmlReader>())); mockCache.Verify(m => m.CheckAssembly(It.IsAny<Assembly>(), It.IsAny<bool>()), Times.Never()); }
public void ImplicitLoadAllReferencedAssemblies_checks_assembly_and_references_for_views_if_assembly_not_filtered() { var mockCache = new Mock<IViewAssemblyCache>(); var objectItemCollection = new ObjectItemCollection(mockCache.Object); objectItemCollection.ImplicitLoadAllReferencedAssemblies( typeof(FactAttribute).Assembly, new EdmItemCollection(Enumerable.Empty<XmlReader>())); mockCache.Verify(m => m.CheckAssembly(typeof(FactAttribute).Assembly, true), Times.Once()); }
public EFDataModelProvider(object contextInstance, Func<object> contextFactory) { ContextFactory = contextFactory; RelationshipEndLookup = new Dictionary<long, EFColumnProvider>(); TableEndLookup = new Dictionary<EntityType, EFTableProvider>(); _context = (ObjectContext)contextInstance ?? (ObjectContext)CreateContext(); ContextType = _context.GetType(); // get a "container" (a scope at the instance level) EntityContainer container = _context.MetadataWorkspace.GetEntityContainer(_context.DefaultContainerName, DataSpace.CSpace); // load object space metadata _context.MetadataWorkspace.LoadFromAssembly(ContextType.Assembly); _objectSpaceItems = (ObjectItemCollection)_context.MetadataWorkspace.GetItemCollection(DataSpace.OSpace); var tables = new List<TableProvider>(); // Create a dictionary from entity type to entity set. The entity type should be at the root of any inheritance chain. IDictionary<EntityType, EntitySet> entitySetLookup = container.BaseEntitySets.OfType<EntitySet>().ToDictionary(e => e.ElementType); // Create a lookup from parent entity to entity ILookup<EntityType, EntityType> derivedTypesLookup = _context.MetadataWorkspace.GetItems<EntityType>(DataSpace.CSpace).ToLookup(e => (EntityType)e.BaseType); // Keeps track of the current entity set being processed EntitySet currentEntitySet = null; // Do a DFS to get the inheritance hierarchy in order // i.e. Consider the hierarchy // null -> Person // Person -> Employee, Contact // Employee -> SalesPerson, Programmer // We'll walk the children in a depth first order -> Person, Employee, SalesPerson, Programmer, Contact. var objectStack = new Stack<EntityType>(); // Start will null (the root of the hierarchy) objectStack.Push(null); while (objectStack.Any()) { EntityType entityType = objectStack.Pop(); if (entityType != null) { // Update the entity set when we are at another root type (a type without a base type). if (entityType.BaseType == null) { currentEntitySet = entitySetLookup[entityType]; } var table = CreateTableProvider(currentEntitySet, entityType); tables.Add(table); } foreach (EntityType derivedEntityType in derivedTypesLookup[entityType]) { // Push the derived entity types on the stack objectStack.Push(derivedEntityType); } } _tables = tables.AsReadOnly(); }
/// <summary> /// Constrcutor to create an instance of DefaultObjectMappingItemCollection. /// To start with we will create a Schema under which maps will be created. /// </summary> /// <param name="edmCollection"></param> /// <param name="objectCollection"></param> public DefaultObjectMappingItemCollection( EdmItemCollection edmCollection, ObjectItemCollection objectCollection) : base(DataSpace.OCSpace) { Contract.Requires(edmCollection != null); Contract.Requires(objectCollection != null); m_edmCollection = edmCollection; m_objectCollection = objectCollection; LoadPrimitiveMaps(); }
public void ImplicitLoadAllReferencedAssemblies_does_perform_o_space_lookup_if_o_space_types_not_already_loaded() { var mockKnownAssemblies = new Mock<KnownAssembliesSet>(); var objectItemCollection = new ObjectItemCollection(mockKnownAssemblies.Object); objectItemCollection.ImplicitLoadAllReferencedAssemblies( typeof(FactAttribute).Assembly(), new EdmItemCollection(Enumerable.Empty<XmlReader>())); KnownAssemblyEntry _; mockKnownAssemblies.Verify( m => m.TryGetKnownAssembly(typeof(FactAttribute).Assembly(), It.IsAny<object>(), It.IsAny<EdmItemCollection>(), out _)); }
/// <summary> /// Constructor to create an instance of DefaultObjectMappingItemCollection. /// To start with we will create a Schema under which maps will be created. /// </summary> /// <param name="edmCollection"> </param> /// <param name="objectCollection"> </param> public DefaultObjectMappingItemCollection( EdmItemCollection edmCollection, ObjectItemCollection objectCollection) : base(DataSpace.OCSpace) { DebugCheck.NotNull(edmCollection); DebugCheck.NotNull(objectCollection); m_edmCollection = edmCollection; m_objectCollection = objectCollection; LoadPrimitiveMaps(); }
public void ExplicitLoadFromAssembly_does_perform_o_space_lookup_if_o_space_types_not_already_loaded() { var mockKnownAssemblies = new Mock<KnownAssembliesSet>(); var objectItemCollection = new ObjectItemCollection(new Mock<IViewAssemblyCache>().Object, mockKnownAssemblies.Object); objectItemCollection.ExplicitLoadFromAssembly( typeof(FactAttribute).Assembly, new EdmItemCollection(Enumerable.Empty<XmlReader>()), null); KnownAssemblyEntry _; mockKnownAssemblies.Verify( m => m.TryGetKnownAssembly(typeof(FactAttribute).Assembly, It.IsAny<object>(), It.IsAny<EdmItemCollection>(), out _)); }
// <summary> // Constructor to create an instance of DefaultObjectMappingItemCollection. // To start with we will create a Schema under which maps will be created. // </summary> public DefaultObjectMappingItemCollection( EdmItemCollection edmCollection, ObjectItemCollection objectCollection) : base(DataSpace.OCSpace) { DebugCheck.NotNull(edmCollection); DebugCheck.NotNull(objectCollection); _edmCollection = edmCollection; _objectCollection = objectCollection; var cspaceTypes = _edmCollection.GetPrimitiveTypes(); foreach (var type in cspaceTypes) { var ospaceType = _objectCollection.GetMappedPrimitiveType(type.PrimitiveTypeKind); Debug.Assert(ospaceType != null, "all primitive type must have been loaded"); AddInternalMapping(new ObjectTypeMapping(ospaceType, type), _clrTypeIndexes, _edmTypeIndexes); } }
public void LoadTypes(EdmItemCollection edmItemCollection, ObjectItemCollection objectItemCollection) { DebugCheck.NotNull(edmItemCollection); DebugCheck.NotNull(objectItemCollection); foreach (var cSpaceType in edmItemCollection.OfType<EdmType>().Where( t => t.BuiltInTypeKind == BuiltInTypeKind.EntityType || t.BuiltInTypeKind == BuiltInTypeKind.EnumType || t.BuiltInTypeKind == BuiltInTypeKind.ComplexType)) { var clrType = cSpaceType.GetClrType(); if (clrType != null) { var oSpaceType = _typeFactory.TryCreateType(clrType, cSpaceType); if (oSpaceType != null) { Debug.Assert(!_typeFactory.CspaceToOspace.ContainsKey(cSpaceType)); _typeFactory.CspaceToOspace.Add(cSpaceType, oSpaceType); } } else { Debug.Assert(!(cSpaceType is EntityType || cSpaceType is ComplexType || cSpaceType is EnumType)); } } _typeFactory.CreateRelationships(edmItemCollection); foreach (var resolve in _typeFactory.ReferenceResolutions) { resolve(); } foreach (var edmType in _typeFactory.LoadedTypes.Values) { edmType.SetReadOnly(); } objectItemCollection.AddLoadedTypes(_typeFactory.LoadedTypes); objectItemCollection.OSpaceTypesLoaded = true; }
/// <summary> /// Loop through all the specified properties, including the children of any complex type properties, looking for enum types. /// </summary> /// <param name="properties">The properties to search.</param> /// <param name="mappingFragment">Information needed from ef metadata to map table and its columns</param> /// <param name="objectItemCollection">For looking up ClrTypes of any enums encountered</param> /// <returns>All the references that were found in a form suitable for creating lookup tables and foreign keys</returns> private static IEnumerable<EnumReference> ProcessEdmProperties(IEnumerable<EdmProperty> properties, MappingFragment mappingFragment, ObjectItemCollection objectItemCollection) { var references = new List<EnumReference>(); // get mapped table name from mapping, or fall-back to just the name if no mapping is set, // I have no idea what causes Table to be null, and I have no unit test for it yet, but I have seen it. var table = mappingFragment.StoreEntitySet.Table ?? mappingFragment.StoreEntitySet.Name; foreach (var edmProperty in properties) { if (edmProperty.IsEnumType) { references.Add(new EnumReference { ReferencingTable = table, ReferencingField = GetColumnName(mappingFragment, edmProperty), EnumType = objectItemCollection.GetClrType(edmProperty.EnumType), }); continue; } if (edmProperty.IsComplexType) { // Note that complex types can't be nested (ref http://stackoverflow.com/a/20332503/10245 ) // so it's safe to not recurse even though the data model suggests you should have to. references.AddRange( from nestedProperty in edmProperty.ComplexType.Properties where nestedProperty.IsEnumType select new EnumReference { ReferencingTable = table, ReferencingField = GetColumnName(mappingFragment, edmProperty, nestedProperty), EnumType = objectItemCollection.GetClrType(nestedProperty.EnumType), }); } } return references; }
internal static bool TryDetermineCSpaceModelType(Type type, MetadataWorkspace workspace, out EdmType modelEdmType) { Debug.Assert(null != workspace); Type nonNullabelType = TypeSystem.GetNonNullableType(type); // make sure the workspace knows about T workspace.ImplicitLoadAssemblyForType(nonNullabelType, System.Reflection.Assembly.GetCallingAssembly()); ObjectItemCollection objectItemCollection = (ObjectItemCollection)workspace.GetItemCollection(DataSpace.OSpace); EdmType objectEdmType; if (objectItemCollection.TryGetItem <EdmType>(nonNullabelType.FullName, out objectEdmType)) { Map map; if (workspace.TryGetMap(objectEdmType, DataSpace.OCSpace, out map)) { ObjectTypeMapping objectMapping = (ObjectTypeMapping)map; modelEdmType = objectMapping.EdmType; return(true); } } modelEdmType = null; return(false); }
/// <summary> /// Gets a dictionary of all entity types associated with the current DbContext type. /// The key is the EntityType (CSpace) and the value is the CLR type of the generated entity. /// </summary> /// <returns>A dictionary keyed by entity type and returning corresponding CLR type</returns> private Dictionary <EntityType, Type> GetEntityTypesInContext() { Dictionary <EntityType, Type> entities = new Dictionary <EntityType, Type>(); ObjectItemCollection itemCollection = this.MetadataWorkspace.GetItemCollection(DataSpace.OSpace) as ObjectItemCollection; foreach (EntityType objectSpaceEntityType in itemCollection.GetItems <EntityType>()) { Type clrType = itemCollection.GetClrType(objectSpaceEntityType); // Skip the EF CodeFirst specific EdmMetadata type if (DbContextUtilities.CompareWithSystemType(clrType, BusinessLogicClassConstants.EdmMetadataTypeName)) { continue; } StructuralType edmEntityType; if (this.MetadataWorkspace.TryGetEdmSpaceType(objectSpaceEntityType, out edmEntityType)) { entities[(EntityType)edmEntityType] = clrType; } } return(entities); }
private static EntitySet GetTable(Type type, DbContext context) { EntitySet table = null; MetadataWorkspace metadata = ((IObjectContextAdapter)context).ObjectContext.MetadataWorkspace; // Get the part of the model that contains info about the actual CLR types ObjectItemCollection objectItemCollection = (ObjectItemCollection)metadata.GetItemCollection(DataSpace.OSpace); // Get the entity type from the model that maps to the CLR type EntityType entityType = metadata.GetItems <EntityType>(DataSpace.OSpace) .SingleOrDefault(e => objectItemCollection.GetClrType(e) == type); if (entityType != null) { // Get the entity set that uses this entity type EntitySet entitySet = metadata.GetItems <EntityContainer>(DataSpace.CSpace) .SingleOrDefault() ?.EntitySets ?.SingleOrDefault(s => s.ElementType.Name == entityType.Name); if (entitySet != null) { // Find the mapping between conceptual and storage model for this entity set EntitySetMapping mapping = metadata.GetItems <EntityContainerMapping>(DataSpace.CSSpace) .SingleOrDefault() ?.EntitySetMappings ?.SingleOrDefault(s => s.EntitySet == entitySet); // Find the storage entity set (table) that the entity is mapped table = mapping?.EntityTypeMappings?.SelectMany(m => m.Fragments.Select(f => f.StoreEntitySet))?.Distinct().FirstOrDefault(); //table = mapping?.EntityTypeMappings.SingleOrDefault()?.Fragments?.SingleOrDefault()?.StoreEntitySet; } } return(table); }
public void LoadFromAssembly_checks_only_given_assembly_for_views() { var mockCache = new Mock<IViewAssemblyCache>(); var objectItemCollection = new ObjectItemCollection(mockCache.Object); objectItemCollection.LoadFromAssembly(typeof(object).Assembly); mockCache.Verify(m => m.CheckAssembly(typeof(object).Assembly, false), Times.Once()); }
public virtual IEnumerable <GlobalItem> GetObjectItemCollection() { return (_objectItemCollection = (ObjectItemCollection)_objectContext.MetadataWorkspace.GetItemCollection(DataSpace.OSpace)); }
private static Type GetClrType(MetadataWorkspace metadata, ObjectItemCollection objectItemCollection, EntitySet set) => GetClrType(metadata, objectItemCollection, set.ElementType);
// <summary> // Search for a Mapping metadata with the specified type key. // </summary> // <param name="identity"> identity of the type </param> // <param name="typeSpace"> The dataspace that the type for which map needs to be returned belongs to </param> // <param name="ignoreCase"> true for case-insensitive lookup </param> // <returns> Returns false if no match found. </returns> internal override bool TryGetMap(string identity, DataSpace typeSpace, bool ignoreCase, out MappingBase map) { EdmType cdmType = null; EdmType clrType = null; if (typeSpace == DataSpace.CSpace) { if (ignoreCase) { // Get the correct casing of the identity first if we are asked to do ignore case if (!_edmCollection.TryGetItem(identity, true, out cdmType)) { map = null; return(false); } identity = cdmType.Identity; } int index; if (_edmTypeIndexes.TryGetValue(identity, out index)) { map = (MappingBase)this[index]; return(true); } if (cdmType != null || _edmCollection.TryGetItem(identity, ignoreCase, out cdmType)) { // If the mapping is not already loaded, then get the mapping ospace type _objectCollection.TryGetOSpaceType(cdmType, out clrType); } } else if (typeSpace == DataSpace.OSpace) { if (ignoreCase) { // Get the correct casing of the identity first if we are asked to do ignore case if (!_objectCollection.TryGetItem(identity, true, out clrType)) { map = null; return(false); } identity = clrType.Identity; } int index; if (_clrTypeIndexes.TryGetValue(identity, out index)) { map = (MappingBase)this[index]; return(true); } if (clrType != null || _objectCollection.TryGetItem(identity, ignoreCase, out clrType)) { // If the mapping is not already loaded, get the mapping cspace type var cspaceTypeName = ObjectItemCollection.TryGetMappingCSpaceTypeIdentity(clrType); _edmCollection.TryGetItem(cspaceTypeName, out cdmType); } } if ((clrType == null) || (cdmType == null)) { map = null; return(false); } else { map = GetDefaultMapping(cdmType, clrType); return(true); } }
public EFDataModelProvider(object contextInstance, Func <object> contextFactory) { ContextFactory = contextFactory; RelationshipEndLookup = new Dictionary <long, EFColumnProvider>(); TableEndLookup = new Dictionary <EntityType, EFTableProvider>(); _context = (ObjectContext)contextInstance ?? (ObjectContext)CreateContext(); ContextType = _context.GetType(); // get a "container" (a scope at the instance level) EntityContainer container = _context.MetadataWorkspace.GetEntityContainer(_context.DefaultContainerName, DataSpace.CSpace); // load object space metadata _context.MetadataWorkspace.LoadFromAssembly(ContextType.Assembly); _objectSpaceItems = (ObjectItemCollection)_context.MetadataWorkspace.GetItemCollection(DataSpace.OSpace); var tables = new List <TableProvider>(); // Create a dictionary from entity type to entity set. The entity type should be at the root of any inheritance chain. IDictionary <EntityType, EntitySet> entitySetLookup = container.BaseEntitySets.OfType <EntitySet>().ToDictionary(e => e.ElementType); // Create a lookup from parent entity to entity ILookup <EntityType, EntityType> derivedTypesLookup = _context.MetadataWorkspace.GetItems <EntityType>(DataSpace.CSpace).ToLookup(e => (EntityType)e.BaseType); // Keeps track of the current entity set being processed EntitySet currentEntitySet = null; // Do a DFS to get the inheritance hierarchy in order // i.e. Consider the hierarchy // null -> Person // Person -> Employee, Contact // Employee -> SalesPerson, Programmer // We'll walk the children in a depth first order -> Person, Employee, SalesPerson, Programmer, Contact. var objectStack = new Stack <EntityType>(); // Start will null (the root of the hierarchy) objectStack.Push(null); while (objectStack.Any()) { EntityType entityType = objectStack.Pop(); if (entityType != null) { // Update the entity set when we are at another root type (a type without a base type). if (entityType.BaseType == null) { currentEntitySet = entitySetLookup[entityType]; } var table = CreateTableProvider(currentEntitySet, entityType); tables.Add(table); } foreach (EntityType derivedEntityType in derivedTypesLookup[entityType]) { // Push the derived entity types on the stack objectStack.Push(derivedEntityType); } } _tables = tables.AsReadOnly(); }
private Type GetClrTypeFromTypeMapping(MetadataWorkspace metadata, ObjectItemCollection objectItemCollection, EntityTypeMapping mapping) { return GetClrType(metadata, objectItemCollection, mapping.EntityType ?? mapping.IsOfEntityTypes.First()); }
public void Can_load_entity_with_property_of_enum_type_from_different_assembly() { const bool isPOCO = true; var enumTypeCsdl = XDocument.Parse( @"<Schema xmlns=""http://schemas.microsoft.com/ado/2009/11/edm"" Namespace=""EnumModel""> <EnumType Name=""Enum"" IsFlags=""false"" /> </Schema>"); var entityTypeCsdl = XDocument.Parse( @"<Schema xmlns=""http://schemas.microsoft.com/ado/2009/11/edm"" Namespace=""EnumModel""> <EntityContainer Name=""EnumModelContainer""> <EntitySet Name=""Entity"" EntityType=""EnumModel.Entity"" /> </EntityContainer> <EntityType Name=""Entity""> <Key> <PropertyRef Name=""Id"" /> </Key> <Property Name=""Id"" Nullable=""false"" Type=""Int32"" /> <Property Name=""EnumProperty"" Nullable=""false"" Type=""EnumModel.Enum"" /> </EntityType> </Schema>"); var assemblyWithEnumType = BuildAssembly(isPOCO, enumTypeCsdl); var assemblyWithEntityType = BuildAssembly(isPOCO, entityTypeCsdl); EdmItemCollection edmItemCollection; using (var enumTypeReader = enumTypeCsdl.CreateReader()) { using (var entityTypeReader = entityTypeCsdl.CreateReader()) { edmItemCollection = new EdmItemCollection( new[] { enumTypeReader, entityTypeReader }); } } var objectItemCollection = new ObjectItemCollection(); objectItemCollection.LoadFromAssembly(assemblyWithEnumType, edmItemCollection); objectItemCollection.LoadFromAssembly(assemblyWithEntityType, edmItemCollection); var workspace = new MetadataWorkspace( () => edmItemCollection, () => null, () => null, () => objectItemCollection); Assert.Equal( "EnumModel.Entity:EnumModel.Entity", workspace.GetMap("EnumModel.Entity", DataSpace.OSpace, DataSpace.OCSpace).Identity); }
public EFCodeFirstDataModelProvider(Func<DbContext> dbContextFactory) { // First, instantiate a DbContext just to get the type its type ContextType = dbContextFactory().GetType(); // This is the code that gets called anytime an ObjectContext needs to be created ContextFactory = () => { // Create the DbContext and get the underlying ObjectContext out of it DbContext dbContext = dbContextFactory(); var context = ((IObjectContextAdapter)dbContext).ObjectContext; // Set the DefaultContainerName to the context name if it's not set if (String.IsNullOrEmpty(context.DefaultContainerName)) { context.DefaultContainerName = ContextType.Name; } // Load the workspace from the context's assembly // See http://social.msdn.microsoft.com/Forums/en-US/adonetefx/thread/53fc5d64-5ff3-4e9f-ae7c-795d1eb750d2 context.MetadataWorkspace.LoadFromAssembly(ContextType.Assembly); return context; }; RelationshipEndLookup = new Dictionary<long, EFCodeFirstColumnProvider>(); TableEndLookup = new Dictionary<EntityType, EFCodeFirstTableProvider>(); _objectContext = ContextFactory(); // get a "container" (a scope at the instance level) EntityContainer container = _objectContext.MetadataWorkspace.GetEntityContainer(_objectContext.DefaultContainerName, DataSpace.CSpace); _objectSpaceItems = (ObjectItemCollection)_objectContext.MetadataWorkspace.GetItemCollection(DataSpace.OSpace); var tables = new List<TableProvider>(); // Create a dictionary from entity type to entity set. The entity type should be at the root of any inheritance chain. IDictionary<EntityType, EntitySet> entitySetLookup = container.BaseEntitySets.OfType<EntitySet>().ToDictionary(e => e.ElementType); // Create a lookup from parent entity to entity ILookup<EntityType, EntityType> derivedTypesLookup = _objectContext.MetadataWorkspace.GetItems<EntityType>(DataSpace.CSpace).ToLookup(e => (EntityType)e.BaseType); // Keeps track of the current entity set being processed EntitySet currentEntitySet = null; // Do a DFS to get the inheritance hierarchy in order // i.e. Consider the hierarchy // null -> Person // Person -> Employee, Contact // Employee -> SalesPerson, Programmer // We'll walk the children in a depth first order -> Person, Employee, SalesPerson, Programmer, Contact. var objectStack = new Stack<EntityType>(); // Start will null (the root of the hierarchy) objectStack.Push(null); while (objectStack.Any()) { EntityType entityType = objectStack.Pop(); if (entityType != null) { // Update the entity set when we are at another root type (a type without a base type). if (entityType.BaseType == null) { currentEntitySet = entitySetLookup[entityType]; } // Ignore the special EdmMetadatas table, which is an implementation detail of EF Code First if (currentEntitySet.Name != "EdmMetadatas") { var table = CreateTableProvider(currentEntitySet, entityType); tables.Add(table); } } foreach (EntityType derivedEntityType in derivedTypesLookup[entityType]) { // Push the derived entity types on the stack objectStack.Push(derivedEntityType); } } _tables = tables.AsReadOnly(); }
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)); }
/// <summary> /// Loop through all the specified properties, including the children of any complex type properties, looking for enum types. /// </summary> /// <param name="properties">The properties to search.</param> /// <param name="mappingFragment">Information needed from ef metadata to map table and its columns</param> /// <param name="objectItemCollection">For looking up ClrTypes of any enums encountered</param> /// <returns>All the references that were found in a form suitable for creating lookup tables and foreign keys</returns> private static IEnumerable <EnumReference> ProcessEdmProperties(IEnumerable <EdmProperty> properties, MappingFragment mappingFragment, ObjectItemCollection objectItemCollection) { var references = new List <EnumReference>(); // get mapped table name from mapping, or fall-back to just the name if no mapping is set, // I have no idea what causes Table to be null, and I have no unit test for it yet, but I have seen it. var table = mappingFragment.StoreEntitySet.Table ?? mappingFragment.StoreEntitySet.Name; foreach (var edmProperty in properties) { if (edmProperty.IsEnumType) { var propertyMapping = GetPropertyMapping(mappingFragment.PropertyMappings, edmProperty); var propertyColumnName = GetColumnNameFromPropertyMapping(edmProperty, propertyMapping); references.Add(new EnumReference { ReferencingTable = table, ReferencingField = propertyColumnName, EnumType = objectItemCollection.GetClrType(edmProperty.EnumType), }); continue; } if (edmProperty.IsComplexType) { // Use a queue to be able to process nested complex properties // A kvp is stored where key item is the complex property and the value item is property mapping for that complex property Queue <KeyValuePair <EdmProperty, ComplexPropertyMapping> > complexPropertyQueue = new Queue <KeyValuePair <EdmProperty, ComplexPropertyMapping> >(); complexPropertyQueue.Enqueue(new KeyValuePair <EdmProperty, ComplexPropertyMapping>( edmProperty, GetComplexPropertyMapping(mappingFragment.PropertyMappings, edmProperty) )); do { //this loop adds references to enum properties from within the complex type and also //processes nested complex properties recursively by utilizing the queue. //the search is done in BFS fashion var complexPropAndContainingProperties = complexPropertyQueue.Dequeue(); var prop = complexPropAndContainingProperties.Key; var propertyMapping = complexPropAndContainingProperties.Value; references.AddRange( (from nestedProperty in prop.ComplexType.Properties where nestedProperty.IsEnumType select new EnumReference { ReferencingTable = table, ReferencingField = GetColumnNameForEnumWithinComplexProperty(propertyMapping, prop, nestedProperty), EnumType = objectItemCollection.GetClrType(nestedProperty.EnumType), }).ToArray()); var subPropertyMappings = propertyMapping .TypeMappings .Single(p => p.ComplexType.Name == prop.ComplexType.Name) .PropertyMappings; foreach (var nestedComplex in prop.ComplexType.Properties.Where(p => p.IsComplexType)) { complexPropertyQueue.Enqueue(new KeyValuePair <EdmProperty, ComplexPropertyMapping>( nestedComplex, GetComplexPropertyMapping(subPropertyMappings, nestedComplex) )); } } while (complexPropertyQueue.Any()); } } return(references); }
/// <summary> /// Loop through all the specified properties, including the children of any complex type properties, looking for enum types. /// </summary> /// <param name="properties">The properties to search.</param> /// <param name="mappingFragment">Information needed from ef metadata to map table and its columns</param> /// <param name="objectItemCollection">For looking up ClrTypes of any enums encountered</param> /// <returns>All the references that were found in a form suitable for creating lookup tables and foreign keys</returns> private static IEnumerable <EnumReference> ProcessEdmProperties(IEnumerable <EdmProperty> properties, MappingFragment mappingFragment, ObjectItemCollection objectItemCollection) { var references = new List <EnumReference>(); // get mapped table name from mapping, or fall-back to just the name if no mapping is set, // I have no idea what causes Table to be null, and I have no unit test for it yet, but I have seen it. var table = mappingFragment.StoreEntitySet.Table ?? mappingFragment.StoreEntitySet.Name; var schema = mappingFragment.StoreEntitySet.Schema; foreach (var edmProperty in properties) { if (edmProperty.IsEnumType) { references.Add(new EnumReference { ReferencingTableSchema = schema, ReferencingTable = table, ReferencingField = GetColumnName(mappingFragment, edmProperty), EnumType = objectItemCollection.GetClrType(edmProperty.EnumType), }); continue; } if (edmProperty.IsComplexType) { // Note that complex types can't be nested (ref http://stackoverflow.com/a/20332503/10245 ) // so it's safe to not recurse even though the data model suggests you should have to. references.AddRange( from nestedProperty in edmProperty.ComplexType.Properties where nestedProperty.IsEnumType select new EnumReference { ReferencingTableSchema = schema, ReferencingTable = table, ReferencingField = GetColumnName(mappingFragment, edmProperty, nestedProperty), EnumType = objectItemCollection.GetClrType(nestedProperty.EnumType), }); } } return(references); }
private static Type GetClrType(MetadataWorkspace metadata, ObjectItemCollection objectItemCollection, EntityTypeBase type) { return metadata .GetItems<EntityType>(DataSpace.OSpace) .Select(objectItemCollection.GetClrType) .Single(e => e.Name == type.Name); }
public void ImplicitLoadAssemblyForType_checks_assemblies_of_generics_for_views_if_assembly_not_filtered() { var mockCache = new Mock<IViewAssemblyCache>(); var objectItemCollection = new ObjectItemCollection(mockCache.Object); objectItemCollection.ImplicitLoadAssemblyForType( typeof(Dictionary<FactAttribute, FactAttribute>), new EdmItemCollection(Enumerable.Empty<XmlReader>())); mockCache.Verify(m => m.CheckAssembly(typeof(FactAttribute).Assembly, false), Times.Exactly(2)); }
private static MetadataWorkspace CreateMetadataWorkspace(XDocument cSpaceCsdl, Assembly assembly, bool isPOCO) { EdmItemCollection edmItemCollection; using (var csdlReader = cSpaceCsdl.CreateReader()) { edmItemCollection = new EdmItemCollection(new[] { csdlReader }); } // assembly can actually be an AssemblyBuilder. The following line ensures that we are // using the actual assembly otherwise an Assert in ObjectItemAttributeAssemblyLoader.LoadType // will fire. assembly = assembly.GetTypes().First().Assembly(); var objectItemCollection = new ObjectItemCollection(); if (isPOCO) { objectItemCollection.LoadFromAssembly(assembly, edmItemCollection); } else { objectItemCollection.LoadFromAssembly(assembly); } var workspace = new MetadataWorkspace( () => edmItemCollection, () => null, () => null, () => objectItemCollection); return workspace; }
public void Registering_c_space_or_o_space_does_not_cause_oc_mapping_to_be_registered_if_it_is_already_registered() { var edmItemCollection = new EdmItemCollection(new[] { XDocument.Parse(Csdl).CreateReader() }); var objectItemCollection = new ObjectItemCollection(); var ocMappingItemCollection = new DefaultObjectMappingItemCollection(edmItemCollection, objectItemCollection); var workspace = new MetadataWorkspace(); #pragma warning disable 612,618 workspace.RegisterItemCollection(ocMappingItemCollection); workspace.RegisterItemCollection(edmItemCollection); workspace.RegisterItemCollection(objectItemCollection); #pragma warning restore 612,618 Assert.Same(ocMappingItemCollection, workspace.GetItemCollection(DataSpace.OCSpace)); Assert.Same(edmItemCollection, workspace.GetItemCollection(DataSpace.CSpace)); Assert.Same(objectItemCollection, workspace.GetItemCollection(DataSpace.OSpace)); }
private static Type GetClrType(MetadataWorkspace metadata, ObjectItemCollection objectItemCollection, EntitySet set) { return GetClrType(metadata, objectItemCollection, set.ElementType); }
/// <summary> /// Tries to collect the views from the referenced assemblies of Entry assembly. /// </summary> /// <param name="workspace"> </param> private void SerializedCollectViewsFromReferencedAssemblies( MetadataWorkspace workspace, Dictionary<EntitySetBase, GeneratedView> extentMappingViews) { ObjectItemCollection objectCollection; ItemCollection itemCollection; if (!workspace.TryGetItemCollection(DataSpace.OSpace, out itemCollection)) { //Possible enhancement : Think about achieving the same thing without creating Object Item Collection. objectCollection = new ObjectItemCollection(); itemCollection = objectCollection; // The GetEntryAssembly method can return a null reference //when a managed assembly has been loaded from an unmanaged application. var entryAssembly = Assembly.GetEntryAssembly(); if (entryAssembly != null) { objectCollection.ImplicitLoadViewsFromAllReferencedAssemblies(entryAssembly); } } SerializedCollectViewsFromObjectCollection(workspace, extentMappingViews); }
/// <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 void Four_delegates_constructor_uses_given_delegates_and_sets_up_default_oc_mapping() { var edmItemCollection = new EdmItemCollection(new[] { XDocument.Parse(_csdlV3).CreateReader() }); var storeItemCollection = new StoreItemCollection(new[] { XDocument.Parse(_ssdlV3).CreateReader() }); var objectItemCollection = new ObjectItemCollection(); var storageMappingItemCollection = LoadMsl(edmItemCollection, storeItemCollection); var workspace = new MetadataWorkspace( () => edmItemCollection, () => storeItemCollection, () => storageMappingItemCollection, () => objectItemCollection); Assert.Same(edmItemCollection, workspace.GetItemCollection(DataSpace.CSpace)); Assert.Same(storeItemCollection, workspace.GetItemCollection(DataSpace.SSpace)); Assert.Same(storageMappingItemCollection, workspace.GetItemCollection(DataSpace.CSSpace)); Assert.Same(objectItemCollection, workspace.GetItemCollection(DataSpace.OSpace)); var ocMappingCollection = (DefaultObjectMappingItemCollection)workspace.GetItemCollection(DataSpace.OCSpace); Assert.Same(objectItemCollection, ocMappingCollection.ObjectItemCollection); Assert.Same(edmItemCollection, ocMappingCollection.EdmItemCollection); }
internal override bool TryGetMap( string identity, DataSpace typeSpace, bool ignoreCase, out MappingBase map) { EdmType edmType1 = (EdmType)null; EdmType edmType2 = (EdmType)null; switch (typeSpace) { case DataSpace.OSpace: if (ignoreCase) { if (!this._objectCollection.TryGetItem <EdmType>(identity, true, out edmType2)) { map = (MappingBase)null; return(false); } identity = edmType2.Identity; } int index1; if (this._clrTypeIndexes.TryGetValue(identity, out index1)) { map = (MappingBase)this[index1]; return(true); } if (edmType2 != null || this._objectCollection.TryGetItem <EdmType>(identity, ignoreCase, out edmType2)) { this._edmCollection.TryGetItem <EdmType>(ObjectItemCollection.TryGetMappingCSpaceTypeIdentity(edmType2), out edmType1); break; } break; case DataSpace.CSpace: if (ignoreCase) { if (!this._edmCollection.TryGetItem <EdmType>(identity, true, out edmType1)) { map = (MappingBase)null; return(false); } identity = edmType1.Identity; } int index2; if (this._edmTypeIndexes.TryGetValue(identity, out index2)) { map = (MappingBase)this[index2]; return(true); } if (edmType1 != null || this._edmCollection.TryGetItem <EdmType>(identity, ignoreCase, out edmType1)) { this._objectCollection.TryGetOSpaceType(edmType1, out edmType2); break; } break; } if (edmType2 == null || edmType1 == null) { map = (MappingBase)null; return(false); } map = this.GetDefaultMapping(edmType1, edmType2); return(true); }
public void ImplicitLoadAssemblyForType_does_not_perform_o_space_lookup_if_o_space_types_already_loaded() { var mockKnownAssemblies = new Mock<KnownAssembliesSet>(); var objectItemCollection = new ObjectItemCollection(mockKnownAssemblies.Object); objectItemCollection.OSpaceTypesLoaded = true; objectItemCollection.ImplicitLoadAssemblyForType( typeof(Dictionary<FactAttribute, FactAttribute>), new EdmItemCollection(Enumerable.Empty<XmlReader>())); KnownAssemblyEntry _; mockKnownAssemblies.Verify( m => m.TryGetKnownAssembly(It.IsAny<Assembly>(), It.IsAny<object>(), It.IsAny<EdmItemCollection>(), out _), Times.Never()); }
private static void ValidateMembersMatch(EdmMember edmMember, EdmMember objectMember) { Debug.Assert(edmMember.DeclaringType.DataSpace == DataSpace.CSpace, "the cspace member is not on a cspace type"); Debug.Assert(objectMember.DeclaringType.DataSpace == DataSpace.OSpace, "the ospace member is not on a cspace type"); // Make sure the property type is the same if (edmMember.BuiltInTypeKind != objectMember.BuiltInTypeKind) { throw new MappingException( Strings.Mapping_Default_OCMapping_MemberKind_Mismatch( edmMember.Name, edmMember.DeclaringType.FullName, edmMember.BuiltInTypeKind, objectMember.Name, objectMember.DeclaringType.FullName, objectMember.BuiltInTypeKind)); } // Make sure the member type is the same if (edmMember.TypeUsage.EdmType.BuiltInTypeKind != objectMember.TypeUsage.EdmType.BuiltInTypeKind) { throw Error.Mapping_Default_OCMapping_Member_Type_Mismatch( edmMember.TypeUsage.EdmType.Name, edmMember.TypeUsage.EdmType.BuiltInTypeKind, edmMember.Name, edmMember.DeclaringType.FullName, objectMember.TypeUsage.EdmType.Name, objectMember.TypeUsage.EdmType.BuiltInTypeKind, objectMember.Name, objectMember.DeclaringType.FullName); } if (Helper.IsPrimitiveType(edmMember.TypeUsage.EdmType)) { var memberType = Helper.GetSpatialNormalizedPrimitiveType(edmMember.TypeUsage.EdmType); // We expect the CLR primitive type and their corresponding EDM primitive types to have the same primitive type kind (at least for now) if (memberType.PrimitiveTypeKind != ((PrimitiveType)objectMember.TypeUsage.EdmType).PrimitiveTypeKind) { throw new MappingException( Strings.Mapping_Default_OCMapping_Invalid_MemberType( edmMember.TypeUsage.EdmType.FullName, edmMember.Name, edmMember.DeclaringType.FullName, objectMember.TypeUsage.EdmType.FullName, objectMember.Name, objectMember.DeclaringType.FullName)); } } else if (Helper.IsEnumType(edmMember.TypeUsage.EdmType)) { Debug.Assert( Helper.IsEnumType(objectMember.TypeUsage.EdmType), "Both types are expected to by EnumTypes. For non-matching types we should have already thrown."); ValidateEnumTypeMapping((EnumType)edmMember.TypeUsage.EdmType, (EnumType)objectMember.TypeUsage.EdmType); } else { EdmType edmMemberType; EdmType objectMemberType; if (BuiltInTypeKind.AssociationEndMember == edmMember.BuiltInTypeKind) { edmMemberType = ((RefType)edmMember.TypeUsage.EdmType).ElementType; objectMemberType = ((RefType)objectMember.TypeUsage.EdmType).ElementType; } else if (BuiltInTypeKind.NavigationProperty == edmMember.BuiltInTypeKind && Helper.IsCollectionType(edmMember.TypeUsage.EdmType)) { edmMemberType = ((CollectionType)edmMember.TypeUsage.EdmType).TypeUsage.EdmType; objectMemberType = ((CollectionType)objectMember.TypeUsage.EdmType).TypeUsage.EdmType; } else { edmMemberType = edmMember.TypeUsage.EdmType; objectMemberType = objectMember.TypeUsage.EdmType; } if (edmMemberType.Identity != ObjectItemCollection.TryGetMappingCSpaceTypeIdentity(objectMemberType)) { throw new MappingException( Strings.Mapping_Default_OCMapping_Invalid_MemberType( edmMember.TypeUsage.EdmType.FullName, edmMember.Name, edmMember.DeclaringType.FullName, objectMember.TypeUsage.EdmType.FullName, objectMember.Name, objectMember.DeclaringType.FullName)); } } }
Registering_o_space_causes_oc_mapping_to_also_be_registered_if_it_is_not_already_registered_and_c_space_is_registered() { var edmItemCollection = new EdmItemCollection(new[] { XDocument.Parse(_csdlV3).CreateReader() }); var objectItemCollection = new ObjectItemCollection(); var workspace = new MetadataWorkspace(); #pragma warning disable 612,618 workspace.RegisterItemCollection(edmItemCollection); workspace.RegisterItemCollection(objectItemCollection); #pragma warning restore 612,618 Assert.Same(edmItemCollection, workspace.GetItemCollection(DataSpace.CSpace)); Assert.Same(objectItemCollection, workspace.GetItemCollection(DataSpace.OSpace)); var ocMappingCollection = (DefaultObjectMappingItemCollection)workspace.GetItemCollection(DataSpace.OCSpace); Assert.Same(objectItemCollection, ocMappingCollection.ObjectItemCollection); Assert.Same(edmItemCollection, ocMappingCollection.EdmItemCollection); }
private Type GetClrTypeFromTypeMapping(MetadataWorkspace metadata, ObjectItemCollection objectItemCollection, EntityTypeMapping mapping) => GetClrType(metadata, objectItemCollection, mapping.EntityType ?? mapping.IsOfEntityTypes.First());
public void Registering_o_space_does_not_cause_oc_mapping_to_be_registered_if_c_space_is_not_registered() { var objectItemCollection = new ObjectItemCollection(); var workspace = new MetadataWorkspace(); #pragma warning disable 612,618 workspace.RegisterItemCollection(objectItemCollection); #pragma warning restore 612,618 Assert.Same(objectItemCollection, workspace.GetItemCollection(DataSpace.OSpace)); ItemCollection _; Assert.False(workspace.TryGetItemCollection(DataSpace.OCSpace, out _)); }
public virtual IEnumerable<GlobalItem> GetObjectItemCollection() { return _objectItemCollection = (ObjectItemCollection)_objectContext.MetadataWorkspace.GetItemCollection(DataSpace.OSpace); }
/// <summary> /// Initializes an instance of the EfMappingHelper class. /// </summary> /// <param name="db">The Entity Framework DbContext to get the mapping from.</param> public EfMappingHelper(DbContext db) { // Get a reference to the metadata workspace, from where we can retrieve information about all parts of the model. MetadataWorkspace metadata = ((IObjectContextAdapter)db).ObjectContext.MetadataWorkspace; // Conceptual part of the model has info about the shape of our entity classes. ReadOnlyCollection <EntityContainer> conceptualEntityContainers = metadata.GetItems <EntityContainer>(DataSpace.CSpace); EntityContainer conceptualContainer = conceptualEntityContainers.SingleOrDefault(); if (conceptualContainer == null) { return; } // Storage part of the model has info about the shape of our tables. ReadOnlyCollection <EntityContainer> storeContainers = metadata.GetItems <EntityContainer>(DataSpace.SSpace); EntityContainer storeContainer = storeContainers.SingleOrDefault(); if (storeContainer == null) { return; } // Object part of the model that contains info about the actual CLR types. ObjectItemCollection objectItemCollection = (ObjectItemCollection)metadata.GetItemCollection(DataSpace.OSpace); ReadOnlyCollection <EntityType> objectContainers = metadata.GetItems <EntityType>(DataSpace.OSpace); // Mapping part of model is not public, so we need to write to XML. XDocument edmx = GetEdmx(db); // Set up results. List <EfEntityMapping> entityMappings = new List <EfEntityMapping>(); List <EfRelationshipMapping> relationshipMappings = new List <EfRelationshipMapping>(); List <EfTable> tables = new List <EfTable>(); // Look through each entity in the conceptual model, and retrieve how each entity is mapped to the tables in the // storage part of the model. // // Remember that it is theoretically possible that multiple entities could be mapped to the same database table, // i.e. Table Splitting, or that one entity could be mapped to multiple database tables, i.e. "Entity Splitting". // Therefore when it comes to checking against the database, if multiple entities are mapped to the same table, // we can make sure that each of those entities have the correct data types mapped in all cases. // // Exclude the EdmMetadata table which is a table that EF may have created itself. foreach (EntitySet set in conceptualContainer.BaseEntitySets.OfType <EntitySet>().Where(e => e.Name != "EdmMetadatas")) { EfEntityMapping entityMapping = new EfEntityMapping { TableMappings = new List <EfTableMapping>() }; entityMappings.Add(entityMapping); if (objectContainers != null) { // Get the CLR type of the entity. entityMapping.EntityType = objectContainers.Select(objectItemCollection.GetClrType) .Single(e => e.Name == set.ElementType.Name); // Get the mapping fragments for this type. NOTE: Types may have multiple fragments if Entity Splitting is used. XElement element = edmx.Descendants() .SingleOrDefault(e => e.Name.LocalName == "EntityTypeMapping" && e.Attribute("TypeName")?.Value == set.ElementType.FullName); if (element != null) { IEnumerable <XElement> mappingFragments = element.Descendants() .Where(e => e.Name.LocalName == "MappingFragment"); foreach (XElement mapping in mappingFragments) { EfTableMapping tableMapping = new EfTableMapping { PropertyMappings = new List <EfPropertyMapping>() }; entityMapping.TableMappings.Add(tableMapping); // Find the table and schema that this fragment maps to. string storeSet = mapping.Attribute("StoreEntitySet")?.Value; tableMapping.TableName = (string)storeContainer .BaseEntitySets.OfType <EntitySet>() .Single(s => s.Name == storeSet) .MetadataProperties["Table"].Value; tableMapping.SchemaName = (string)storeContainer .BaseEntitySets.OfType <EntitySet>() .Single(s => s.Name == storeSet) .MetadataProperties["Schema"].Value; // Find the property-to-column mappings. IEnumerable <XElement> propertyMappings = mapping .Descendants() .Where(e => e.Name.LocalName == "ScalarProperty"); foreach (XElement propertyMapping in propertyMappings) { // Find the property and column being mapped. string propertyName = propertyMapping.Attribute("Name")?.Value ?? string.Empty; string columnName = propertyMapping.Attribute("ColumnName")?.Value ?? string.Empty; // Get the information about the property from the actual CLR class. PropertyInfo propertyInfo = entityMapping.EntityType.GetProperty(propertyName); if (propertyInfo != null) { // Get the infromation about the property from the entity model metadata. EdmProperty edmProperty = set.ElementType.Properties.Single(e => e.Name == propertyName); Facet maxLengthFacet = edmProperty.TypeUsage.Facets.SingleOrDefault(f => f.Name == "MaxLength"); int maxLength; // The only meaningful "max lengths" are from strings and binary values. // // If the property on the entity model is an enumeration, then check that the underlying type of // the enumeration is what is compared with the database. // // Use reflection to retrieve the data type defined for the property on the entity itself. PrimitiveTypeKind primitiveTypeKind = PrimitiveTypeKind.Binary; Type primitivePropertyType = null; if (edmProperty.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.EnumType) { primitiveTypeKind = edmProperty.UnderlyingPrimitiveType.PrimitiveTypeKind; // Some special handling here if there is a Nullable enumeration. If the enumeration // is nullable then the nullableEnum will be populated. Type nullableEnum = Nullable.GetUnderlyingType(propertyInfo.PropertyType); // If we're dealing with a nullable enumeration, we then have to create a nullable version of the underlying type // to compare the database schema with. Otherwise we can just call Enum.GetUnderlyingType to get the non-nullable version. primitivePropertyType = nullableEnum != null ? typeof(Nullable <>).MakeGenericType(Enum.GetUnderlyingType(nullableEnum)) : Enum.GetUnderlyingType(propertyInfo.PropertyType); } else if (edmProperty.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType) { primitiveTypeKind = ((PrimitiveType)edmProperty.TypeUsage.EdmType).PrimitiveTypeKind; primitivePropertyType = propertyInfo.PropertyType; } if ((primitiveTypeKind == PrimitiveTypeKind.Binary || primitiveTypeKind == PrimitiveTypeKind.String) && maxLengthFacet != null) { // The contents of MaxLength might be the string "Max" for columns in SQL Server like // varchar(max). Therefore return -1 in these cases because this is also how SQL Server reports // the column length in its own metadata. All other values for strings with maximum lengths // should just return a numeric value. if (edmProperty.TypeUsage.Facets["MaxLength"].Value.ToString() == "Max") { maxLength = -1; } else { maxLength = (int)edmProperty.TypeUsage.Facets["MaxLength"].Value; } } else { maxLength = 0; } tableMapping.PropertyMappings.Add(new EfPropertyMapping { PropertyType = primitivePropertyType, ColumnName = columnName, IsNullable = edmProperty.Nullable, MaximumLength = maxLength }); } } } } } } // At this point, we have retrieved all of the tables that our conceptual model has mapped to, however this won't necessarily // include all of the "join" tables that are part of many-many relationships. The conceptual mapping doesn't list these tables, // therefore we have to look in the storage part of the model to actually get the list of tables that EF "knows" about. foreach (EntitySet set in storeContainer.BaseEntitySets.OfType <EntitySet>().Where(e => e.Name != "EdmMetadatas")) { EfTable table = new EfTable { TableName = set.MetadataProperties["Table"].Value.ToString(), SchemaName = set.MetadataProperties["Schema"].Value.ToString() }; tables.Add(table); } // Look through all associations configured in the "store" part of the model. These should map to the primary and foreign keys in the database. foreach (AssociationSet set in storeContainer.BaseEntitySets.OfType <AssociationSet>()) { foreach (ReferentialConstraint constraint in set.ElementType.ReferentialConstraints) { EfRelationshipMapping relationshipMapping = new EfRelationshipMapping { FromProperties = constraint.FromProperties.Select(x => x.Name).ToArray(), FromTable = storeContainer.BaseEntitySets.OfType <EntitySet>().Single(e => e.Name == constraint.FromRole.Name).Table, ToProperties = constraint.ToProperties.Select(x => x.Name).ToArray(), ToTable = storeContainer.BaseEntitySets.OfType <EntitySet>().Single(e => e.Name == constraint.ToRole.Name).Table }; relationshipMappings.Add(relationshipMapping); } } // Return results. EntityMappings = entityMappings.ToArray(); Tables = tables.ToArray(); RelationshipMappings = relationshipMappings.ToArray(); }
private static void Item_collections_can_be_registered(MetadataWorkspace workspace) { var edmItemCollection = new EdmItemCollection(new[] { XDocument.Parse(_csdlV3).CreateReader() }); var storeItemCollection = new StoreItemCollection(new[] { XDocument.Parse(_ssdlV3).CreateReader() }); var objectItemCollection = new ObjectItemCollection(); var storageMappingItemCollection = LoadMsl(edmItemCollection, storeItemCollection); var ocMappingItemCollection = new DefaultObjectMappingItemCollection(edmItemCollection, objectItemCollection); #pragma warning disable 612,618 workspace.RegisterItemCollection(edmItemCollection); workspace.RegisterItemCollection(storeItemCollection); workspace.RegisterItemCollection(objectItemCollection); workspace.RegisterItemCollection(storageMappingItemCollection); workspace.RegisterItemCollection(ocMappingItemCollection); #pragma warning restore 612,618 Assert.Same(edmItemCollection, workspace.GetItemCollection(DataSpace.CSpace)); Assert.Same(storeItemCollection, workspace.GetItemCollection(DataSpace.SSpace)); Assert.Same(storageMappingItemCollection, workspace.GetItemCollection(DataSpace.CSSpace)); Assert.Same(objectItemCollection, workspace.GetItemCollection(DataSpace.OSpace)); Assert.Same(ocMappingItemCollection, workspace.GetItemCollection(DataSpace.OCSpace)); }
public void LoadFromAssembly_does_not_perform_o_space_lookup_if_o_space_types_already_loaded() { var mockKnownAssemblies = new Mock<KnownAssembliesSet>(); var objectItemCollection = new ObjectItemCollection(new Mock<IViewAssemblyCache>().Object, mockKnownAssemblies.Object); objectItemCollection.OSpaceTypesLoaded = true; objectItemCollection.LoadFromAssembly(typeof(FactAttribute).Assembly); objectItemCollection.LoadFromAssembly( typeof(FactAttribute).Assembly, new EdmItemCollection(Enumerable.Empty<XmlReader>())); objectItemCollection.LoadFromAssembly( typeof(FactAttribute).Assembly, new EdmItemCollection(Enumerable.Empty<XmlReader>()), s => { }); KnownAssemblyEntry _; mockKnownAssemblies.Verify( m => m.TryGetKnownAssembly(It.IsAny<Assembly>(), It.IsAny<object>(), It.IsAny<EdmItemCollection>(), out _), Times.Never()); }