internal bool TryCreateFunctionImportMappingComposableWithStructuralResult( EdmFunction functionImport, EdmFunction cTypeTargetFunction, List<FunctionImportStructuralTypeMapping> typeMappings, RowType cTypeTvfElementType, RowType sTypeTvfElementType, IXmlLineInfo lineInfo, out FunctionImportMappingComposable mapping) { mapping = null; // If it is an implicit structural type mapping, add a type mapping fragment for the return type of the function import, // unless it is an abstract type. if (typeMappings.Count == 0) { StructuralType resultType; if (MetadataHelper.TryGetFunctionImportReturnType(functionImport, 0, out resultType)) { if (resultType.Abstract) { AddToSchemaErrorWithMemberAndStructure( Strings.Mapping_FunctionImport_ImplicitMappingForAbstractReturnType, resultType.FullName, functionImport.Identity, MappingErrorCode.MappingOfAbstractType, m_sourceLocation, lineInfo, m_parsingErrors); return false; } if (resultType.BuiltInTypeKind == BuiltInTypeKind.EntityType) { typeMappings.Add( new FunctionImportEntityTypeMapping( Enumerable.Empty<EntityType>(), new[] { (EntityType)resultType }, Enumerable.Empty<FunctionImportEntityTypeMappingCondition>(), new Collection<FunctionImportReturnTypePropertyMapping>(), new LineInfo(lineInfo))); } else { Debug.Assert( resultType.BuiltInTypeKind == BuiltInTypeKind.ComplexType, "resultType.BuiltInTypeKind == BuiltInTypeKind.ComplexType"); typeMappings.Add( new FunctionImportComplexTypeMapping( (ComplexType)resultType, new Collection<FunctionImportReturnTypePropertyMapping>(), new LineInfo(lineInfo))); } } } // when this method is invoked when a CodeFirst model is being built (e.g. from a custom convention) the // StorageMappingItemCollection will be null. In this case we can provide an empty EdmItemCollection which // will allow inferring implicit result mapping var edmItemCollection = _entityContainerMapping.StorageMappingItemCollection != null ? _entityContainerMapping.StorageMappingItemCollection.EdmItemCollection : new EdmItemCollection(new EdmModel(DataSpace.CSpace)); // Validate and convert FunctionImportEntityTypeMapping elements into structure suitable for composable function import mapping. var functionImportKB = new FunctionImportStructuralTypeMappingKB(typeMappings, edmItemCollection); var structuralTypeMappings = new List<Tuple<StructuralType, List<ConditionPropertyMapping>, List<PropertyMapping>>>(); EdmProperty[] targetFunctionKeys = null; if (functionImportKB.MappedEntityTypes.Count > 0) { // Validate TPH ambiguity. if (!functionImportKB.ValidateTypeConditions( /*validateAmbiguity: */true, m_parsingErrors, m_sourceLocation)) { return false; } // For each mapped entity type, prepare list of conditions and list of property mappings. for (var i = 0; i < functionImportKB.MappedEntityTypes.Count; ++i) { List<ConditionPropertyMapping> typeConditions; List<PropertyMapping> propertyMappings; if (TryConvertToEntityTypeConditionsAndPropertyMappings( functionImport, functionImportKB, i, cTypeTvfElementType, sTypeTvfElementType, lineInfo, out typeConditions, out propertyMappings)) { structuralTypeMappings.Add( Tuple.Create((StructuralType)functionImportKB.MappedEntityTypes[i], typeConditions, propertyMappings)); } } if (structuralTypeMappings.Count < functionImportKB.MappedEntityTypes.Count) { // Some of the entity types produced errors during conversion, exit. return false; } // Infer target function keys based on the c-space entity types. if (!TryInferTVFKeys(structuralTypeMappings, out targetFunctionKeys)) { AddToSchemaErrorsWithMemberInfo( Strings.Mapping_FunctionImport_CannotInferTargetFunctionKeys, functionImport.Identity, MappingErrorCode.MappingFunctionImportCannotInferTargetFunctionKeys, m_sourceLocation, lineInfo, m_parsingErrors); return false; } } else { ComplexType resultComplexType; if (MetadataHelper.TryGetFunctionImportReturnType(functionImport, 0, out resultComplexType)) { // Gather and validate complex type property mappings. List<PropertyMapping> propertyMappings; if ( !TryConvertToPropertyMappings( resultComplexType, cTypeTvfElementType, sTypeTvfElementType, functionImport, functionImportKB, lineInfo, out propertyMappings)) { return false; } structuralTypeMappings.Add( Tuple.Create((StructuralType)resultComplexType, new List<ConditionPropertyMapping>(), propertyMappings)); } else { Debug.Fail("Function import return type is expected to be a collection of complex type."); } } mapping = new FunctionImportMappingComposable( functionImport, cTypeTargetFunction, structuralTypeMappings, targetFunctionKeys, _entityContainerMapping); return true; }
internal bool TryCreateFunctionImportMappingComposableWithStructuralResult( EdmFunction functionImport, EdmFunction cTypeTargetFunction, List <FunctionImportStructuralTypeMapping> typeMappings, RowType cTypeTvfElementType, RowType sTypeTvfElementType, IXmlLineInfo lineInfo, out FunctionImportMappingComposable mapping) { mapping = null; // If it is an implicit structural type mapping, add a type mapping fragment for the return type of the function import, // unless it is an abstract type. if (typeMappings.Count == 0) { StructuralType resultType; if (MetadataHelper.TryGetFunctionImportReturnType(functionImport, 0, out resultType)) { if (resultType.Abstract) { AddToSchemaErrorWithMemberAndStructure( Strings.Mapping_FunctionImport_ImplicitMappingForAbstractReturnType, resultType.FullName, functionImport.Identity, MappingErrorCode.MappingOfAbstractType, m_sourceLocation, lineInfo, m_parsingErrors); return(false); } if (resultType.BuiltInTypeKind == BuiltInTypeKind.EntityType) { typeMappings.Add( new FunctionImportEntityTypeMapping( Enumerable.Empty <EntityType>(), new[] { (EntityType)resultType }, Enumerable.Empty <FunctionImportEntityTypeMappingCondition>(), new Collection <FunctionImportReturnTypePropertyMapping>(), new LineInfo(lineInfo))); } else { Debug.Assert( resultType.BuiltInTypeKind == BuiltInTypeKind.ComplexType, "resultType.BuiltInTypeKind == BuiltInTypeKind.ComplexType"); typeMappings.Add( new FunctionImportComplexTypeMapping( (ComplexType)resultType, new Collection <FunctionImportReturnTypePropertyMapping>(), new LineInfo(lineInfo))); } } } // when this method is invoked when a CodeFirst model is being built (e.g. from a custom convention) the // StorageMappingItemCollection will be null. In this case we can provide an empty EdmItemCollection which // will allow inferring implicit result mapping var edmItemCollection = _entityContainerMapping.StorageMappingItemCollection != null ? _entityContainerMapping.StorageMappingItemCollection.EdmItemCollection : new EdmItemCollection(new EdmModel(DataSpace.CSpace)); // Validate and convert FunctionImportEntityTypeMapping elements into structure suitable for composable function import mapping. var functionImportKB = new FunctionImportStructuralTypeMappingKB(typeMappings, edmItemCollection); var structuralTypeMappings = new List <Tuple <StructuralType, List <ConditionPropertyMapping>, List <PropertyMapping> > >(); EdmProperty[] targetFunctionKeys = null; if (functionImportKB.MappedEntityTypes.Count > 0) { // Validate TPH ambiguity. if (!functionImportKB.ValidateTypeConditions(/*validateAmbiguity: */ true, m_parsingErrors, m_sourceLocation)) { return(false); } // For each mapped entity type, prepare list of conditions and list of property mappings. for (var i = 0; i < functionImportKB.MappedEntityTypes.Count; ++i) { List <ConditionPropertyMapping> typeConditions; List <PropertyMapping> propertyMappings; if (TryConvertToEntityTypeConditionsAndPropertyMappings( functionImport, functionImportKB, i, cTypeTvfElementType, sTypeTvfElementType, lineInfo, out typeConditions, out propertyMappings)) { structuralTypeMappings.Add( Tuple.Create((StructuralType)functionImportKB.MappedEntityTypes[i], typeConditions, propertyMappings)); } } if (structuralTypeMappings.Count < functionImportKB.MappedEntityTypes.Count) { // Some of the entity types produced errors during conversion, exit. return(false); } // Infer target function keys based on the c-space entity types. if (!TryInferTVFKeys(structuralTypeMappings, out targetFunctionKeys)) { AddToSchemaErrorsWithMemberInfo( Strings.Mapping_FunctionImport_CannotInferTargetFunctionKeys, functionImport.Identity, MappingErrorCode.MappingFunctionImportCannotInferTargetFunctionKeys, m_sourceLocation, lineInfo, m_parsingErrors); return(false); } } else { ComplexType resultComplexType; if (MetadataHelper.TryGetFunctionImportReturnType(functionImport, 0, out resultComplexType)) { // Gather and validate complex type property mappings. List <PropertyMapping> propertyMappings; if ( !TryConvertToPropertyMappings( resultComplexType, cTypeTvfElementType, sTypeTvfElementType, functionImport, functionImportKB, lineInfo, out propertyMappings)) { return(false); } structuralTypeMappings.Add( Tuple.Create((StructuralType)resultComplexType, new List <ConditionPropertyMapping>(), propertyMappings)); } else { Debug.Fail("Function import return type is expected to be a collection of complex type."); } } mapping = new FunctionImportMappingComposable( functionImport, cTypeTargetFunction, structuralTypeMappings, targetFunctionKeys, _entityContainerMapping); return(true); }
internal bool TryCreateFunctionImportMappingComposableWithStructuralResult( EdmFunction functionImport, EdmFunction cTypeTargetFunction, List <FunctionImportStructuralTypeMapping> typeMappings, RowType cTypeTvfElementType, RowType sTypeTvfElementType, IXmlLineInfo lineInfo, out FunctionImportMappingComposable mapping) { mapping = (FunctionImportMappingComposable)null; StructuralType returnType1; if (typeMappings.Count == 0 && MetadataHelper.TryGetFunctionImportReturnType <StructuralType>(functionImport, 0, out returnType1)) { if (returnType1.Abstract) { FunctionImportMappingComposableHelper.AddToSchemaErrorWithMemberAndStructure(new Func <object, object, string>(Strings.Mapping_FunctionImport_ImplicitMappingForAbstractReturnType), returnType1.FullName, functionImport.Identity, MappingErrorCode.MappingOfAbstractType, this.m_sourceLocation, lineInfo, (IList <EdmSchemaError>) this.m_parsingErrors); return(false); } if (returnType1.BuiltInTypeKind == BuiltInTypeKind.EntityType) { typeMappings.Add((FunctionImportStructuralTypeMapping) new FunctionImportEntityTypeMapping(Enumerable.Empty <System.Data.Entity.Core.Metadata.Edm.EntityType>(), (IEnumerable <System.Data.Entity.Core.Metadata.Edm.EntityType>) new System.Data.Entity.Core.Metadata.Edm.EntityType[1] { (System.Data.Entity.Core.Metadata.Edm.EntityType)returnType1 }, Enumerable.Empty <FunctionImportEntityTypeMappingCondition>(), new Collection <FunctionImportReturnTypePropertyMapping>(), new LineInfo(lineInfo))); } else { typeMappings.Add((FunctionImportStructuralTypeMapping) new FunctionImportComplexTypeMapping((ComplexType)returnType1, new Collection <FunctionImportReturnTypePropertyMapping>(), new LineInfo(lineInfo))); } } EdmItemCollection edmItemCollection = this._entityContainerMapping.StorageMappingItemCollection != null ? this._entityContainerMapping.StorageMappingItemCollection.EdmItemCollection : new EdmItemCollection(new EdmModel(DataSpace.CSpace, 3.0)); FunctionImportStructuralTypeMappingKB functionImportKB = new FunctionImportStructuralTypeMappingKB((IEnumerable <FunctionImportStructuralTypeMapping>)typeMappings, (ItemCollection)edmItemCollection); List <Tuple <StructuralType, List <ConditionPropertyMapping>, List <PropertyMapping> > > structuralTypeMappings = new List <Tuple <StructuralType, List <ConditionPropertyMapping>, List <PropertyMapping> > >(); EdmProperty[] keys = (EdmProperty[])null; if (functionImportKB.MappedEntityTypes.Count > 0) { if (!functionImportKB.ValidateTypeConditions(true, (IList <EdmSchemaError>) this.m_parsingErrors, this.m_sourceLocation)) { return(false); } for (int typeID = 0; typeID < functionImportKB.MappedEntityTypes.Count; ++typeID) { List <ConditionPropertyMapping> typeConditions; List <PropertyMapping> propertyMappings; if (this.TryConvertToEntityTypeConditionsAndPropertyMappings(functionImport, functionImportKB, typeID, cTypeTvfElementType, sTypeTvfElementType, lineInfo, out typeConditions, out propertyMappings)) { structuralTypeMappings.Add(Tuple.Create <StructuralType, List <ConditionPropertyMapping>, List <PropertyMapping> >((StructuralType)functionImportKB.MappedEntityTypes[typeID], typeConditions, propertyMappings)); } } if (structuralTypeMappings.Count < functionImportKB.MappedEntityTypes.Count) { return(false); } if (!FunctionImportMappingComposableHelper.TryInferTVFKeys(structuralTypeMappings, out keys)) { FunctionImportMappingComposableHelper.AddToSchemaErrorsWithMemberInfo(new Func <object, string>(Strings.Mapping_FunctionImport_CannotInferTargetFunctionKeys), functionImport.Identity, MappingErrorCode.MappingFunctionImportCannotInferTargetFunctionKeys, this.m_sourceLocation, lineInfo, (IList <EdmSchemaError>) this.m_parsingErrors); return(false); } } else { ComplexType returnType2; if (MetadataHelper.TryGetFunctionImportReturnType <ComplexType>(functionImport, 0, out returnType2)) { List <PropertyMapping> propertyMappings; if (!this.TryConvertToPropertyMappings((StructuralType)returnType2, cTypeTvfElementType, sTypeTvfElementType, functionImport, functionImportKB, lineInfo, out propertyMappings)) { return(false); } structuralTypeMappings.Add(Tuple.Create <StructuralType, List <ConditionPropertyMapping>, List <PropertyMapping> >((StructuralType)returnType2, new List <ConditionPropertyMapping>(), propertyMappings)); } } mapping = new FunctionImportMappingComposable(functionImport, cTypeTargetFunction, structuralTypeMappings, keys, this._entityContainerMapping); return(true); }