public void Generate(EdmEntityType entityType, DbDatabaseMapping databaseMapping) { //Contract.Requires(entityType != null); //Contract.Requires(databaseMapping != null); var entitySet = databaseMapping.Model.GetEntitySet(entityType); var entitySetMapping = databaseMapping.GetEntitySetMapping(entitySet) ?? databaseMapping.AddEntitySetMapping(entitySet); var table = entitySetMapping.EntityTypeMappings.Any() ? entitySetMapping.EntityTypeMappings.First().TypeMappingFragments.First().Table : databaseMapping.Database.AddTable(entityType.GetRootType().Name); var entityTypeMappingFragment = new DbEntityTypeMappingFragment { Table = table }; var entityTypeMapping = new DbEntityTypeMapping { EntityType = entityType, IsHierarchyMapping = false }; entityTypeMapping.TypeMappingFragments.Add(entityTypeMappingFragment); entityTypeMapping.SetClrType(entityType.GetClrType()); entitySetMapping.EntityTypeMappings.Add(entityTypeMapping); new PropertyMappingGenerator(_providerManifest) .Generate( entityType, entityType.Properties, entitySetMapping, entityTypeMappingFragment, new List<EdmProperty>(), false); }
private void ConfigureKey(EdmEntityType entityType) { Contract.Requires(entityType != null); if (!_keyProperties.Any()) { return; } if (entityType.BaseType != null) { throw Error.KeyRegisteredOnDerivedType(ClrType, entityType.GetRootType().GetClrType()); } var keyProperties = _keyProperties.AsEnumerable(); if (!_isKeyConfigured) { var primaryKeys = from p in _keyProperties select new { PropertyInfo = p, Property(new PropertyPath(p)).ColumnOrder }; if ((_keyProperties.Count > 1) && primaryKeys.Any(p => !p.ColumnOrder.HasValue)) { throw Error.ModelGeneration_UnableToDetermineKeyOrder(ClrType); } keyProperties = primaryKeys.OrderBy(p => p.ColumnOrder).Select(p => p.PropertyInfo); } foreach (var keyProperty in keyProperties) { var property = entityType.GetDeclaredPrimitiveProperty(keyProperty); if (property == null) { throw Error.KeyPropertyNotFound(keyProperty.Name, entityType.Name); } property.PropertyType.IsNullable = false; entityType.DeclaredKeyProperties.Add(property); } }
public static EdmEntitySet GetEntitySet(this EdmModel model, EdmEntityType entityType) { //Contract.Requires(model != null); //Contract.Requires(entityType != null); Contract.Assert(model.Containers.Count == 1); return model.GetEntitySets().SingleOrDefault(e => e.ElementType == entityType.GetRootType()); }
private static bool UpdateColumnNamesForTableSharing( DbDatabaseMapping databaseMapping, EdmEntityType entityType, DbTableMetadata toTable, DbEntityTypeMappingFragment fragment) { // Validate: this table can be used only if: // 1. The table is not used by any other type // 2. The table is used only by types in the same type hierarchy (TPH) // 3. There is a 1:1 relationship and the PK count and types match (Table Splitting) var typesSharingTable = FindAllTypesUsingTable(databaseMapping, toTable); var associationsToSharedTable = new Dictionary<EdmEntityType, List<EdmAssociationType>>(); foreach (var candidateType in typesSharingTable) { var oneToOneAssocations = FindAllOneToOneFKAssociationTypes( databaseMapping.Model, entityType, candidateType); var rootType = candidateType.GetRootType(); if (!associationsToSharedTable.ContainsKey(rootType)) { associationsToSharedTable.Add(rootType, oneToOneAssocations.ToList()); } else { associationsToSharedTable[rootType].AddRange(oneToOneAssocations); } } foreach (var candidateTypePair in associationsToSharedTable) { // Check if these types are in a TPH hierarchy if (candidateTypePair.Key != entityType.GetRootType() && candidateTypePair.Value.Count == 0) { var tableName = toTable.GetTableName(); throw Error.EntityMappingConfiguration_InvalidTableSharing( entityType.Name, candidateTypePair.Key.Name, tableName != null ? tableName.Name : toTable.DatabaseIdentifier); } } var allAssociations = associationsToSharedTable.Values.SelectMany(l => l); if (allAssociations.Any()) { var principalKeyNamesType = toTable.GetKeyNamesType(); if (principalKeyNamesType == null) { // grab a candidate var association = allAssociations.First(); principalKeyNamesType = association.Constraint.PrincipalEnd(association).EntityType; if (allAssociations.All(x => x.Constraint.PrincipalEnd(x).EntityType == principalKeyNamesType)) { toTable.SetKeyNamesType(principalKeyNamesType); } } // rename the columns in the fragment to match the principal keys var principalKeys = principalKeyNamesType.KeyProperties().ToArray(); var i = 0; foreach (var k in entityType.KeyProperties()) { var dependentColumn = fragment.PropertyMappings.Single(pm => pm.PropertyPath.First() == k).Column; dependentColumn.Name = principalKeys[i].Name; i++; } return true; } return false; }
public void Generate( EdmEntityType entityType, IEnumerable<EdmProperty> properties, DbEntitySetMapping entitySetMapping, DbEntityTypeMappingFragment entityTypeMappingFragment, IList<EdmProperty> propertyPath, bool createNewColumn) { Contract.Requires(entityType != null); Contract.Requires(properties != null); Contract.Requires(entityTypeMappingFragment != null); Contract.Requires(propertyPath != null); var rootDeclaredProperties = entityType.GetRootType().DeclaredProperties; foreach (var property in properties) { if (property.PropertyType.IsComplexType && propertyPath.Any( p => p.PropertyType.IsComplexType && (p.PropertyType.ComplexType == property.PropertyType.ComplexType))) { throw Error.CircularComplexTypeHierarchy(); } propertyPath.Add(property); if (property.PropertyType.IsComplexType) { Generate( entityType, property.PropertyType.ComplexType.DeclaredProperties, entitySetMapping, entityTypeMappingFragment, propertyPath, createNewColumn); } else { var tableColumn = entitySetMapping.EntityTypeMappings .SelectMany(etm => etm.TypeMappingFragments) .SelectMany(etmf => etmf.PropertyMappings) .Where(pm => pm.PropertyPath.SequenceEqual(propertyPath)) .Select(pm => pm.Column) .FirstOrDefault(); if (tableColumn == null || createNewColumn) { tableColumn = entityTypeMappingFragment.Table.AddColumn( string.Join("_", propertyPath.Select(p => p.Name))); MapTableColumn( property, tableColumn, !rootDeclaredProperties.Contains(propertyPath.First()), entityType.KeyProperties().Contains(property)); } entityTypeMappingFragment.PropertyMappings.Add( new DbEdmPropertyMapping { Column = tableColumn, PropertyPath = propertyPath.ToList() }); } propertyPath.Remove(property); } }
public void GetRootType_should_return_base_type_when_has_base_type() { var entityType = new EdmEntityType { BaseType = new EdmEntityType() }; Assert.Same(entityType.BaseType, entityType.GetRootType()); }
public void GetRootType_should_return_same_type_when_no_base_type() { var entityType = new EdmEntityType(); Assert.Same(entityType, entityType.GetRootType()); }