// internal for testing internal static EdmProperty GenerateScalarProperty( SimpleMappingContext mappingContext, EdmProperty storeProperty, UniqueIdentifierService uniquePropertyNameService) { Debug.Assert(storeProperty != null, "storeProperty != null"); Debug.Assert(uniquePropertyNameService != null, "uniquePropertyNameService != null"); var conceptualPropertyName = CreateModelName(storeProperty.Name, uniquePropertyNameService); var conceptualProperty = EdmProperty.Create(conceptualPropertyName, storeProperty.TypeUsage.ModelTypeUsage); if (storeProperty.StoreGeneratedPattern != StoreGeneratedPattern.None) { conceptualProperty.SetMetadataProperties( new List <MetadataProperty> { CreateAnnotationMetadataProperty( "StoreGeneratedPattern", Enum.GetName( typeof(StoreGeneratedPattern), storeProperty.StoreGeneratedPattern)) }); } mappingContext.AddMapping(storeProperty, conceptualProperty); return(conceptualProperty); }
private EdmType CreateReturnRowType(string propertyName, EdmType edmType) { if (edmType.BuiltInTypeKind == BuiltInTypeKind.EntityType) { var propertyToSoreTypeUsage = FindStoreTypeUsages((EntityType)edmType); return (RowType.Create( ((EntityType)edmType).Properties.Select( m => EdmProperty.Create(m.Name, propertyToSoreTypeUsage[m])), null)); } if (edmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType) { return (RowType.Create( ((StructuralType)edmType).Members.Select( m => EdmProperty.Create(m.Name, GetStorePrimitiveTypeUsage(m.TypeUsage))), null)); } if (edmType.BuiltInTypeKind == BuiltInTypeKind.EnumType) { return(RowType.Create(new[] { EdmProperty.Create(propertyName, GetStorePrimitiveTypeUsage(TypeUsage.CreateDefaultTypeUsage(((EnumType)edmType).UnderlyingType))) }, null)); } return (RowType.Create( new[] { EdmProperty.Create(propertyName, GetStorePrimitiveTypeUsage(TypeUsage.CreateDefaultTypeUsage(edmType))) }, null)); }
public void Crate_creates_store_function_for_complex_type_function_import() { var model = new DbModelBuilder() .Build(new DbProviderInfo("System.Data.SqlClient", "2012")); var complexType = ComplexType.Create("CT", "ns", DataSpace.CSpace, new[] { EdmProperty.Create("Street", TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String))), EdmProperty.Create("ZipCode", TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32))), }, null); var functionDescriptor = new FunctionDescriptor( "f", new[] { new ParameterDescriptor("p1", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), null, false) }, new EdmType[] { complexType }, "ResultCol", "dbo", StoreFunctionKind.StoredProcedure); var storeFunction = new StoreFunctionBuilder(model, "docs", "ns").Create(functionDescriptor); Assert.Null(storeFunction.ReturnParameter); Assert.Equal(1, storeFunction.Parameters.Count); Assert.Equal("p1", storeFunction.Parameters[0].Name); Assert.Equal("nvarchar(max)", storeFunction.Parameters[0].TypeName); Assert.Equal(ParameterMode.In, storeFunction.Parameters[0].Mode); Assert.False(storeFunction.IsComposableAttribute); }
public EdmProperty Build <T>(string name, Action <EdmProperty> action) { var property = EdmProperty.Create(name, this.typeUsageFactory.Create <T>()); action(property); return(property); }
private static EdmType CreateResultType(DbModel model, ResultDescriptor result) { EdmType edmType = GetSimpleEdmType(model, result.Type); if (edmType == null) { edmType = GetStructuralEdmType(model, result.Type); } if (edmType == null) { throw new InvalidOperationException(string.Format("Edm type is not found for result type {0}.", result.Type.FullName)); } switch (edmType.BuiltInTypeKind) { case BuiltInTypeKind.EntityType: var propertyMappings = ((EntityType)edmType).Properties.Join( model.ConceptualToStoreMapping.EntitySetMappings .SelectMany(t => t.EntityTypeMappings) .Where(t => edmType.Yield(e => e.BaseType, (e, b) => b, e => e != null).Contains(t.EntityType)) .SelectMany(tm => tm.Fragments.SelectMany(t => t.PropertyMappings)) .OfType <ScalarPropertyMapping>(), p => p, pm => pm.Property, (p, pm) => new { Property = p, TypeUsage = TypeUsage.Create(pm.Column.TypeUsage.EdmType, pm.Column.TypeUsage.Facets.Where(f => !new[] { "StoreGeneratedPattern", "ConcurrencyMode" }.Contains(f.Name))) }); return(RowType.Create(propertyMappings.Select(pm => EdmProperty.Create(pm.Property.Name, pm.TypeUsage)), null)); case BuiltInTypeKind.ComplexType: return(RowType.Create(((StructuralType)edmType).Members.Select(m => { string columnName = null; MetadataProperty metadata; //if (!m.MetadataProperties.TryGetValue("Configuration", true, out metadata) || !metadata.Value.TryGetProperty("ColumnName", out columnName)) if (m.MetadataProperties.TryGetValue("ClrAttributes", true, out metadata)) { var columnAttr = ((IEnumerable)m.MetadataProperties["ClrAttributes"].Value).OfType <ColumnAttribute>().SingleOrDefault(); if (columnAttr != null && !string.IsNullOrEmpty(columnAttr.Name)) { columnName = columnAttr.Name; } } return EdmProperty.Create(columnName ?? m.Name, model.ProviderManifest.GetStoreType(m.TypeUsage)); }), null)); case BuiltInTypeKind.EnumType: return(RowType.Create(new[] { EdmProperty.CreateEnum(result.ColumnName, (EnumType)edmType) }, null)); case BuiltInTypeKind.PrimitiveType: return(RowType.Create(new[] { EdmProperty.CreatePrimitive(result.ColumnName, (PrimitiveType)edmType) }, null)); default: throw new NotSupportedException(); } }
public EdmProperty BuildBinary(string name, bool isFixedLength) { var typeUsage = TypeUsage.CreateBinaryTypeUsage( PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Binary), isFixedLength); var property = EdmProperty.Create( name, typeUsage); return(property); }
private static ComplexType CreateComplexType() { var prop1 = EdmProperty.Create( "Prop1", TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32))); var prop2 = EdmProperty.Create( "Prop2", TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String))); return (ComplexType.Create("TestComplexType", "Model", DataSpace.CSpace, new[] { prop1, prop2 }, null)); }
private static SimpleMappingContext CreateSimpleMappingContext(bool isForeignKey) { var int32TypeUsage = TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32)); var storeP1 = new[] { CreateStoreProperty("storeSourceId", "int") }; var storeP2 = new[] { CreateStoreProperty("storeTargetId", "int") }; var modelP1 = new[] { EdmProperty.Create("modelSourceId", int32TypeUsage) }; var modelP2 = new[] { EdmProperty.Create("modelTargetId", int32TypeUsage) }; var storeET1 = EntityType.Create("storeET1", "N", DataSpace.SSpace, new[] { "storeSourceId" }, storeP1, null); var storeET2 = EntityType.Create("storeET2", "N", DataSpace.SSpace, new[] { "storeTargetId" }, storeP2, null); var modelET1 = EntityType.Create("modelET1", "N", DataSpace.CSpace, new[] { "modelSourceId" }, modelP1, null); var modelET2 = EntityType.Create("modelET2", "N", DataSpace.CSpace, new[] { "modelTargetId" }, modelP2, null); var storeES1 = EntitySet.Create("storeES1", null, null, null, storeET1, null); var storeES2 = EntitySet.Create("storeES2", null, null, null, storeET2, null); var modelES1 = EntitySet.Create("modelES1", null, null, null, modelET1, null); var modelES2 = EntitySet.Create("modelES2", null, null, null, modelET2, null); var storeEM1 = AssociationEndMember.Create( "storeEM1", storeET1.GetReferenceType(), RelationshipMultiplicity.One, OperationAction.None, null); var storeEM2 = AssociationEndMember.Create( "storeEM2", storeET2.GetReferenceType(), RelationshipMultiplicity.One, OperationAction.None, null); var modelEM1 = AssociationEndMember.Create( "modelEM1", modelET1.GetReferenceType(), RelationshipMultiplicity.Many, OperationAction.None, null); var modelEM2 = AssociationEndMember.Create( "modelEM2", modelET2.GetReferenceType(), RelationshipMultiplicity.Many, OperationAction.None, null); var storeRC = new ReferentialConstraint(storeEM1, storeEM2, storeP1, storeP2); var modelRC = new ReferentialConstraint(modelEM1, modelEM2, modelP1, modelP2); var storeAT = AssociationType.Create("storeAT", "N", isForeignKey, DataSpace.SSpace, storeEM1, storeEM2, storeRC, null); var modelAT = AssociationType.Create("modelAT", "N", isForeignKey, DataSpace.CSpace, modelEM1, modelEM2, modelRC, null); var storeAS = AssociationSet.Create("storeAS", storeAT, storeES1, storeES2, null); var modelAS = AssociationSet.Create("modelAS", modelAT, modelES1, modelES2, null); var storeContainer = EntityContainer.Create( "storeContainer", DataSpace.SSpace, new EntitySetBase[] { storeES1, storeES2, storeAS }, null, null); var modelContainer = EntityContainer.Create( "modelContainer", DataSpace.CSpace, new EntitySetBase[] { modelES1, modelES2, modelAS }, null, null); var mappingContext = new SimpleMappingContext(new EdmModel(DataSpace.SSpace), true); mappingContext.AddMapping(storeP1[0], modelP1[0]); mappingContext.AddMapping(storeP2[0], modelP2[0]); mappingContext.AddMapping(storeET1, modelET1); mappingContext.AddMapping(storeET2, modelET2); mappingContext.AddMapping(storeES1, modelES1); mappingContext.AddMapping(storeES2, modelES2); mappingContext.AddMapping(storeEM1, modelEM1); mappingContext.AddMapping(storeEM2, modelEM2); mappingContext.AddMapping(storeAT, modelAT); mappingContext.AddMapping(storeAS, modelAS); mappingContext.AddMapping(storeAS.AssociationSetEnds[0], modelAS.AssociationSetEnds[0]); mappingContext.AddMapping(storeAS.AssociationSetEnds[1], modelAS.AssociationSetEnds[1]); mappingContext.AddMapping(storeContainer, modelContainer); return(mappingContext); }
public void Can_create_composable_function_import_with_scalar_collection_result() { DbProviderManifest providerManifest; var containerMapping = GetContainerMapping(out providerManifest); var cTypeUsageString = TypeUsage.CreateDefaultTypeUsage( PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String)); var sTypeUsageString = providerManifest.GetStoreType(cTypeUsageString); var rowType = RowType.Create( new[] { EdmProperty.Create("C", sTypeUsageString), }, null); var functionImport = EdmFunction.Create( "F", "N", DataSpace.CSpace, new EdmFunctionPayload { IsComposable = true, ReturnParameters = new[] { FunctionParameter.Create("R", cTypeUsageString.EdmType.GetCollectionType(), ParameterMode.ReturnValue) } }, null); var targetFunction = EdmFunction.Create( "SF", "N", DataSpace.SSpace, new EdmFunctionPayload { IsComposable = true, ReturnParameters = new[] { FunctionParameter.Create("R", rowType.GetCollectionType(), ParameterMode.ReturnValue) } }, null); var resultMapping = new FunctionImportResultMapping(); var functionImportMapping = new FunctionImportMappingComposable( functionImport, targetFunction, resultMapping, containerMapping); Assert.Same(resultMapping, functionImportMapping.ResultMapping); Assert.Null(functionImportMapping.StructuralTypeMappings); Assert.Null(functionImportMapping.TvfKeys); }
public EdmProperty BuildString(string name, bool isUnicode, bool isFixedLength) { var typeUsage = TypeUsage.CreateStringTypeUsage( PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), isUnicode, isFixedLength); var property = EdmProperty.Create( name, typeUsage); return(property); }
private static EntityType CreateEntityType() { var idProperty = EdmProperty.Create( "Id", TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32))); var nameProperty = EdmProperty.Create( "Name", TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String))); return (EntityType.Create("TestEntityType", "Model", DataSpace.CSpace, new[] { "Id" }, new[] { idProperty, nameProperty }, null)); }
public List <EdmMember> GetEdmMembers(DbModel model) { List <PropertyInfo> properties = this.mType.GetProperties().ToList(); List <EdmMember> members = new List <EdmMember>(); foreach (PropertyInfo property in properties) { PrimitiveType primitiveType = PrimitiveType.GetEdmPrimitiveTypes().FirstOrDefault(t => t.ClrEquivalentType == property.PropertyType); EdmType edmType = model.ProviderManifest.GetStoreType(TypeUsage.CreateDefaultTypeUsage(primitiveType)).EdmType; TypeUsage typeUsage = TypeUsage.CreateDefaultTypeUsage(edmType); EdmProperty edmProperty = EdmProperty.Create(property.Name, typeUsage); edmProperty.Nullable = false; members.Add(edmProperty); } return(members); }
private static EdmProperty CloneEdmProperty(EdmProperty property) { var clone = EdmProperty.Create(property.Name, property.TypeUsage); clone.CollectionKind = property.CollectionKind; clone.ConcurrencyMode = property.ConcurrencyMode; clone.IsFixedLength = property.IsFixedLength; clone.IsMaxLength = property.IsMaxLength; clone.IsUnicode = property.IsUnicode; clone.MaxLength = property.MaxLength; clone.Precision = property.Precision; clone.Scale = property.Scale; clone.StoreGeneratedPattern = property.StoreGeneratedPattern; clone.SetMetadataProperties( property.MetadataProperties .Where(metadataProerty => !clone.MetadataProperties.Any(cloneMetadataProperty => cloneMetadataProperty.Name.Equals(metadataProerty.Name, StringComparison.Ordinal)))); return(clone); }
public void Crate_creates_store_function_for_complex_type_withEnum_in_TableValuedFunction() { var model = new DbModelBuilder() .Build(new DbProviderInfo("System.Data.SqlClient", "2012")); var enumType = EnumType.Create("TestEnum", "TestNs", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32), false, new EnumMember[] { EnumMember.Create("foo", 1, null) }, null); var complexType = ComplexType.Create("CT", "ns", DataSpace.CSpace, new[] { EdmProperty.Create("Street", TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String))), EdmProperty.Create("ZipCode", TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32))), EdmProperty.Create("MyEnum", TypeUsage.CreateDefaultTypeUsage(enumType)) }, null); var functionDescriptor = new FunctionDescriptor( "f", new[] { new ParameterDescriptor("p1", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), null, false) }, new EdmType[] { complexType }, "ResultCol", "dbo", StoreFunctionKind.TableValuedFunction, isBuiltIn: null, isNiladic: null); var storeFunction = new StoreFunctionBuilder(model, "docs", "ns").Create(functionDescriptor); Assert.Equal( BuiltInTypeKind.CollectionType, storeFunction.ReturnParameter.TypeUsage.EdmType.BuiltInTypeKind); Assert.Single(storeFunction.Parameters); Assert.Equal("p1", storeFunction.Parameters[0].Name); Assert.Equal("nvarchar(max)", storeFunction.Parameters[0].TypeName); Assert.Equal(ParameterMode.In, storeFunction.Parameters[0].Mode); Assert.True(storeFunction.IsComposableAttribute); }
internal static EdmProperty Clone(this EdmProperty property) { EdmProperty clone = EdmProperty.Create(property.Name, property.TypeUsage); clone.CollectionKind = property.CollectionKind; clone.ConcurrencyMode = property.ConcurrencyMode; clone.IsFixedLength = property.IsFixedLength; clone.IsMaxLength = property.IsMaxLength; clone.IsUnicode = property.IsUnicode; clone.MaxLength = property.MaxLength; clone.Precision = property.Precision; clone.Scale = property.Scale; clone.StoreGeneratedPattern = property.StoreGeneratedPattern; clone.SetMetadataProperties(property .MetadataProperties .Where(metadataProerty => !clone .MetadataProperties .Any(cloneMetadataProperty => cloneMetadataProperty.Name.EqualsOrdinal(metadataProerty.Name)))); return(clone); }
private RowType CreateRowTypeFromEntityType(EntityType entityType) { Debug.Assert(entityType != null, "entityType == null"); var types = Tools.GetTypeHierarchy(entityType); var entityTypeMappings = _model.ConceptualToStoreMapping.EntitySetMappings .SelectMany(s => s.EntityTypeMappings) .Where(t => types.Contains(t.EntityType)) .ToArray(); List <EdmProperty> rowTypeProperties = new List <EdmProperty>(); foreach (var property in entityType.Properties) { foreach (var entityTypeMapping in entityTypeMappings) { var propertyMapping = (ScalarPropertyMapping)entityTypeMapping.Fragments.SelectMany(f => f.PropertyMappings) .FirstOrDefault(p => p.Property == property); if (propertyMapping != null) { // we must use the column name and not just the name of the property to support custom column mappings rowTypeProperties.Add(EdmProperty.Create(propertyMapping.Column.Name, TypeUsage.Create( propertyMapping.Column.TypeUsage.EdmType, propertyMapping.Column.TypeUsage.Facets.Where( f => f.Name != "StoreGeneratedPattern" && f.Name != "ConcurrencyMode")))); break; } } } return(RowType.Create(rowTypeProperties, null)); }
public void Can_create_composable_function_import_with_entity_type_collection_result() { DbProviderManifest providerManifest; var containerMapping = GetContainerMapping(out providerManifest); var cTypeUsageInt = TypeUsage.Create( PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32), new[] { Facet.Create(MetadataItem.NullableFacetDescription, false) }); var sTypeUsageInt = TypeUsage.Create( providerManifest.GetStoreType(cTypeUsageInt).EdmType, new[] { Facet.Create(MetadataItem.NullableFacetDescription, false) }); var entityType = EntityType.Create( "RT", "N", DataSpace.CSpace, new[] { "PId" }, new[] { EdmProperty.Create("PId", cTypeUsageInt), EdmProperty.Create("P", cTypeUsageInt), }, null); var rowType = RowType.Create( new[] { EdmProperty.Create("CId", sTypeUsageInt), EdmProperty.Create("C", sTypeUsageInt), }, null); var functionImport = EdmFunction.Create( "F", "N", DataSpace.CSpace, new EdmFunctionPayload { IsComposable = true, ReturnParameters = new[] { FunctionParameter.Create("R", entityType.GetCollectionType(), ParameterMode.ReturnValue) } }, null); var targetFunction = EdmFunction.Create( "SF", "N", DataSpace.SSpace, new EdmFunctionPayload { IsComposable = true, ReturnParameters = new[] { FunctionParameter.Create("R", rowType.GetCollectionType(), ParameterMode.ReturnValue) } }, null); var typeMapping = new FunctionImportEntityTypeMapping( Enumerable.Empty <EntityType>(), new[] { entityType }, new Collection <FunctionImportReturnTypePropertyMapping>() { new FunctionImportReturnTypeScalarPropertyMapping("PId", "CId"), new FunctionImportReturnTypeScalarPropertyMapping("P", "C"), }, Enumerable.Empty <FunctionImportEntityTypeMappingCondition>()); var resultMapping = new FunctionImportResultMapping(); resultMapping.AddTypeMapping(typeMapping); var functionImportMapping = new FunctionImportMappingComposable( functionImport, targetFunction, resultMapping, containerMapping); Assert.Same(resultMapping, functionImportMapping.ResultMapping); Assert.Equal(1, functionImportMapping.StructuralTypeMappings.Count); Assert.Equal(1, functionImportMapping.TvfKeys.Length); Assert.False(resultMapping.IsReadOnly); functionImportMapping.SetReadOnly(); Assert.True(resultMapping.IsReadOnly); }
public void Build_builds_valid_DbDatabaseMapping_for_functions() { var rowTypeProperty = CreateStoreProperty("p1", "int"); var complexTypeProperty = EdmProperty.Create( "p2", TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32))); var functionImportReturnComplexType = ComplexType.Create( "CT", "entityModel", DataSpace.CSpace, new[] { complexTypeProperty }, null); var storeFunction = EdmFunction.Create( "f_s", "storeModel", DataSpace.SSpace, new EdmFunctionPayload { IsComposable = true, IsFunctionImport = false, ReturnParameters = new[] { FunctionParameter.Create( "ReturnType", RowType.Create(new[] { rowTypeProperty }, null).GetCollectionType(), ParameterMode.ReturnValue) } }, null); var functionImport = EdmFunction.Create( "f_c", "entityModel", DataSpace.CSpace, new EdmFunctionPayload { IsComposable = true, IsFunctionImport = true, ReturnParameters = new[] { FunctionParameter.Create( "ReturnType", functionImportReturnComplexType.GetCollectionType(), ParameterMode.ReturnValue) } }, null); var modelContainer = EntityContainer.Create("C_C", DataSpace.CSpace, new EntitySet[0], new[] { functionImport }, null); var storeContainer = EntityContainer.Create("C_S", DataSpace.SSpace, new EntitySet[0], null, null); var storeModel = EdmModel.CreateStoreModel(storeContainer, null, null); storeModel.AddItem(storeFunction); var mappingContext = new SimpleMappingContext(storeModel, true); mappingContext.AddMapping(rowTypeProperty, complexTypeProperty); mappingContext.AddMapping(storeFunction, functionImport); mappingContext.AddMapping(storeContainer, modelContainer); var entityModel = DbDatabaseMappingBuilder.Build(mappingContext).ConceptualModel; Assert.NotNull(entityModel); Assert.Equal(new[] { "f_c" }, entityModel.Containers.Single().FunctionImports.Select(f => f.Name)); Assert.Equal(new[] { "CT" }, entityModel.ComplexTypes.Select(t => t.Name)); }
public void BuildComposableFunctionMapping_creates_valid_function_mapping() { var rowTypeProperty = CreateStoreProperty("p1", "int"); var complexTypeProperty = EdmProperty.Create( "p2", TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32))); var functionImportReturnComplexType = ComplexType.Create( "c", "entityModel", DataSpace.CSpace, new[] { complexTypeProperty }, null); var storeFunction = EdmFunction.Create( "f_s", "storeModel", DataSpace.SSpace, new EdmFunctionPayload { IsComposable = true, IsFunctionImport = false, ReturnParameters = new[] { FunctionParameter.Create( "ReturnType", RowType.Create(new[] { rowTypeProperty }, null).GetCollectionType(), ParameterMode.ReturnValue) } }, null); var functionImport = EdmFunction.Create( "f_c", "entityModel", DataSpace.CSpace, new EdmFunctionPayload { IsComposable = true, IsFunctionImport = false, ReturnParameters = new[] { FunctionParameter.Create( "ReturnType", functionImportReturnComplexType.GetCollectionType(), ParameterMode.ReturnValue) } }, null); var mappingContext = new SimpleMappingContext(new EdmModel(DataSpace.SSpace), true); mappingContext.AddMapping(rowTypeProperty, complexTypeProperty); mappingContext.AddMapping(storeFunction, functionImport); var functionImportMapping = DbDatabaseMappingBuilder.BuildComposableFunctionMapping(storeFunction, mappingContext); Assert.NotNull(functionImportMapping); Assert.Same(storeFunction, functionImportMapping.TargetFunction); Assert.Same(functionImport, functionImportMapping.FunctionImport); var structuralTypeMappings = functionImportMapping.StructuralTypeMappings; Assert.NotNull(structuralTypeMappings); Assert.Same(functionImportReturnComplexType, structuralTypeMappings.Single().Item1); Assert.Empty(structuralTypeMappings.Single().Item2); Assert.Same(complexTypeProperty, structuralTypeMappings.Single().Item3.Single().Property); Assert.Same(rowTypeProperty, ((ScalarPropertyMapping)structuralTypeMappings.Single().Item3.Single()).Column); }
public void BuildAssociationSetMappings_builds_conceptual_association_set_mapping_for_collapsed_store_entity_sets() { #region Setting up many to many relationship in the SSpace Teacher * -- 1 TeacherStudents 1 -- * Teachers var joinStoreEntityType = EntityType.Create( "TeacherStudents", "ns.Store", DataSpace.SSpace, new[] { "JoinTeacherId", "JoinStudentId" }, new[] { CreateStoreProperty("JoinTeacherId", "int"), CreateStoreProperty("JoinStudentId", "int") }, null); var joinStoreEntitySet = EntitySet.Create("TeacherStudentsSet", "dbo", "TeacherStudentTable", null, joinStoreEntityType, null); var storeTeacherEntityType = EntityType.Create( "Teacher", "ns.Store", DataSpace.SSpace, new[] { "TeacherId" }, new[] { CreateStoreProperty("TeacherId", "int") }, null); var storeTeacherEntitySet = EntitySet.Create("TeachersSet", "dbo", "Teachers", null, storeTeacherEntityType, null); var storeStudentEntityType = EntityType.Create( "Student", "ns.Store", DataSpace.SSpace, new[] { "StudentId" }, new[] { CreateStoreProperty("StudentId", "int") }, null); var storeStudentEntitySet = EntitySet.Create("StudentSet", "dbo", "Students", null, storeStudentEntityType, null); var storeTeachersEndMember = AssociationEndMember.Create( "Teachers", storeTeacherEntityType.GetReferenceType(), RelationshipMultiplicity.Many, OperationAction.None, null); var storeTeacherStudentsfromTeachersEndMember = AssociationEndMember.Create( "TeacherStudents_fromTeachers", joinStoreEntityType.GetReferenceType(), RelationshipMultiplicity.One, OperationAction.None, null); var storeTeacherAssociationType = AssociationType.Create( "Teacher_TeacherStudentsAssociationType", "ns.Store", false, DataSpace.SSpace, storeTeachersEndMember, storeTeacherStudentsfromTeachersEndMember, new ReferentialConstraint( storeTeachersEndMember, storeTeacherStudentsfromTeachersEndMember, storeTeacherEntityType.KeyProperties, joinStoreEntityType.KeyProperties.Where(p => p.Name == "JoinTeacherId")), null); var storeTeacherAssociationSet = AssociationSet.Create( "Teacher_TeacherStudents", storeTeacherAssociationType, storeTeacherEntitySet, joinStoreEntitySet, null); var storeStudentsEndMember = AssociationEndMember.Create( "Students", storeStudentEntityType.GetReferenceType(), RelationshipMultiplicity.Many, OperationAction.None, null); var storeTeacherStudentsfromStudentsEndMember = AssociationEndMember.Create( "TeacherStudents_fromStudents", joinStoreEntityType.GetReferenceType(), RelationshipMultiplicity.One, OperationAction.None, null); var storeStudentAssociationType = AssociationType.Create( "Student_TeacherStudentsAssociationType", "ns.Store", false, DataSpace.SSpace, storeStudentsEndMember, storeTeacherStudentsfromStudentsEndMember, new ReferentialConstraint( storeStudentsEndMember, storeTeacherStudentsfromStudentsEndMember, storeStudentEntityType.KeyProperties, joinStoreEntityType.KeyProperties.Where(p => p.Name == "JoinStudentId")), null); var storeStudentAssociationSet = AssociationSet.Create( "Student_TeacherStudents", storeStudentAssociationType, storeStudentEntitySet, joinStoreEntitySet, null); var collapsedAssociationSet = new CollapsibleEntityAssociationSets(joinStoreEntitySet); collapsedAssociationSet.AssociationSets.Add(storeTeacherAssociationSet); collapsedAssociationSet.AssociationSets.Add(storeStudentAssociationSet); #endregion #region Setting up many to many relationship in the CSpace Teacher * -- * Teachers var conceptualContainer = EntityContainer.Create("ConceptualContainer", DataSpace.CSpace, null, null, null); var edmIntTypeUsage = TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32)); var conceptualTeacherEntityType = EntityType.Create( "Teacher", "ns", DataSpace.CSpace, new[] { "TeacherId" }, new[] { EdmProperty.Create("TeacherId", edmIntTypeUsage) }, null); var conceptualTeacherEntitySet = EntitySet.Create("TeachersSet", null, null, null, conceptualTeacherEntityType, null); var conceptualStudentEntityType = EntityType.Create( "Student", "ns", DataSpace.CSpace, new[] { "StudentId" }, new[] { EdmProperty.Create("StudentId", edmIntTypeUsage) }, null); var conceptualStudentEntitySet = EntitySet.Create("StudentSet", "dbo", "Students", null, conceptualStudentEntityType, null); var conceptualTeachersEndMember = AssociationEndMember.Create( "TeachersEnd", conceptualTeacherEntityType.GetReferenceType(), RelationshipMultiplicity.Many, OperationAction.None, null); var conceptualStudentsEndMember = AssociationEndMember.Create( "StudentsEnd", conceptualStudentEntityType.GetReferenceType(), RelationshipMultiplicity.Many, OperationAction.None, null); var conceptualAssociationType = AssociationType.Create( "TeacherStudentAssociation", "ns.Model", false, DataSpace.CSpace, conceptualTeachersEndMember, conceptualStudentsEndMember, new ReferentialConstraint( conceptualTeachersEndMember, conceptualStudentsEndMember, conceptualTeacherEntityType.KeyProperties, conceptualStudentEntityType.KeyProperties), null); var conceptualAssociationSet = AssociationSet.Create( "TeacherStudentSet", conceptualAssociationType, conceptualTeacherEntitySet, conceptualStudentEntitySet, null); #endregion var mappingContext = new SimpleMappingContext(new EdmModel(DataSpace.SSpace), true); mappingContext.AddMapping(collapsedAssociationSet, conceptualAssociationSet); mappingContext.AddMapping(storeTeachersEndMember, conceptualTeachersEndMember); mappingContext.AddMapping(storeStudentsEndMember, conceptualStudentsEndMember); mappingContext.AddMapping( storeTeacherAssociationSet.AssociationSetEnds.ElementAt(0), conceptualAssociationSet.AssociationSetEnds.ElementAt(0)); mappingContext.AddMapping( storeStudentAssociationSet.AssociationSetEnds.ElementAt(0), conceptualAssociationSet.AssociationSetEnds.ElementAt(1)); mappingContext.AddMapping( storeStudentEntityType.KeyProperties.Single(), conceptualStudentEntityType.KeyProperties.Single()); mappingContext.AddMapping( storeTeacherEntityType.KeyProperties.Single(), conceptualTeacherEntityType.KeyProperties.Single()); var storageEntitySetMapping = new EntityContainerMapping(conceptualContainer, null, null, false, false); var associationSetMapping = DbDatabaseMappingBuilder.BuildAssociationSetMappings(storageEntitySetMapping, mappingContext) .SingleOrDefault(); Assert.NotNull(associationSetMapping); var mappingFragment = associationSetMapping.TypeMappings.SingleOrDefault(); Assert.NotNull(mappingFragment); var propertyMappings = mappingFragment.MappingFragments.Single().PropertyMappings; Assert.Equal(2, propertyMappings.Count); Assert.Same(conceptualTeachersEndMember, ((EndPropertyMapping)propertyMappings[0]).AssociationEnd); Assert.Same(conceptualStudentsEndMember, ((EndPropertyMapping)propertyMappings[1]).AssociationEnd); var scalarPropertyMapping = ((EndPropertyMapping)propertyMappings[0]).PropertyMappings.Single(); Assert.Same(conceptualTeacherEntityType.KeyMembers.Single(), scalarPropertyMapping.Property); Assert.Same( joinStoreEntityType.KeyMembers.Single(m => m.Name == "JoinTeacherId"), scalarPropertyMapping.Column); scalarPropertyMapping = ((EndPropertyMapping)propertyMappings[1]).PropertyMappings.Single(); Assert.Same(conceptualStudentEntityType.KeyMembers.Single(), scalarPropertyMapping.Property); Assert.Same( joinStoreEntityType.KeyMembers.Single(m => m.Name == "JoinStudentId"), scalarPropertyMapping.Column); }
private static DbCompiledModel CreateModel(NpgsqlConnection connection) { var dbModelBuilder = new DbModelBuilder(DbModelBuilderVersion.Latest); // Import Sets dbModelBuilder.Entity <Blog>(); dbModelBuilder.Entity <Post>(); dbModelBuilder.Entity <NoColumnsEntity>(); dbModelBuilder.Entity <User>(); dbModelBuilder.Entity <Editor>(); dbModelBuilder.Entity <Administrator>(); // Import function var dbModel = dbModelBuilder.Build(connection); var edmType = PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32); var addFunc = EdmFunction.Create( "ClrStoredAddFunction", "BloggingContext", DataSpace.SSpace, new EdmFunctionPayload { ParameterTypeSemantics = ParameterTypeSemantics.AllowImplicitConversion, Schema = "dbo", IsComposable = true, IsNiladic = false, IsBuiltIn = false, IsAggregate = false, IsFromProviderManifest = true, StoreFunctionName = "StoredAddFunction", ReturnParameters = new[] { FunctionParameter.Create("ReturnType", edmType, ParameterMode.ReturnValue) }, Parameters = new[] { FunctionParameter.Create("Value1", edmType, ParameterMode.In), FunctionParameter.Create("Value2", edmType, ParameterMode.In) } }, null); dbModel.StoreModel.AddItem(addFunc); var echoFunc = EdmFunction.Create( "StoredEchoFunction", "BloggingContext", DataSpace.SSpace, new EdmFunctionPayload { ParameterTypeSemantics = ParameterTypeSemantics.AllowImplicitConversion, Schema = "dbo", IsComposable = true, IsNiladic = false, IsBuiltIn = false, IsAggregate = false, IsFromProviderManifest = true, StoreFunctionName = null, // intentional ReturnParameters = new[] { FunctionParameter.Create("ReturnType", edmType, ParameterMode.ReturnValue) }, Parameters = new[] { FunctionParameter.Create("Value1", edmType, ParameterMode.In) } }, null); dbModel.StoreModel.AddItem(echoFunc); var stringStoreType = dbModel.ProviderManifest.GetStoreTypes().First(x => x.ClrEquivalentType == typeof(string)); var modelBlogStoreType = dbModel.StoreModel.EntityTypes.First(x => x.Name == typeof(Blog).Name); var rowType = RowType.Create( modelBlogStoreType.Properties.Select(x => { var clone = EdmProperty.Create(x.Name, x.TypeUsage); clone.CollectionKind = x.CollectionKind; clone.ConcurrencyMode = x.ConcurrencyMode; clone.IsFixedLength = x.IsFixedLength; clone.IsMaxLength = x.IsMaxLength; clone.IsUnicode = x.IsUnicode; clone.MaxLength = x.MaxLength; clone.Precision = x.Precision; clone.Scale = x.Scale; clone.StoreGeneratedPattern = x.StoreGeneratedPattern; clone.SetMetadataProperties(x .MetadataProperties .Where(metadataProerty => !clone .MetadataProperties .Any(cloneMetadataProperty => cloneMetadataProperty.Name.Equals(metadataProerty.Name)))); return(clone); }), null); var getBlogsFunc = EdmFunction.Create( "StoredGetBlogsFunction", "BloggingContext", DataSpace.SSpace, new EdmFunctionPayload { ParameterTypeSemantics = ParameterTypeSemantics.AllowImplicitConversion, Schema = "dbo", IsComposable = true, IsNiladic = false, IsBuiltIn = false, IsAggregate = false, StoreFunctionName = "GetBlogsByName", ReturnParameters = new[] { FunctionParameter.Create("ReturnType1", rowType.GetCollectionType(), ParameterMode.ReturnValue) }, Parameters = new[] { FunctionParameter.Create("Name", stringStoreType, ParameterMode.In) } }, null); dbModel.StoreModel.AddItem(getBlogsFunc); var stringPrimitiveType = PrimitiveType.GetEdmPrimitiveTypes().First(x => x.ClrEquivalentType == typeof(string)); var modelBlogConceptualType = dbModel.ConceptualModel.EntityTypes.First(x => x.Name == typeof(Blog).Name); EdmFunction getBlogsFuncModel = EdmFunction.Create( "GetBlogsByName", dbModel.ConceptualModel.Container.Name, DataSpace.CSpace, new EdmFunctionPayload { IsFunctionImport = true, IsComposable = true, Parameters = new[] { FunctionParameter.Create("Name", stringPrimitiveType, ParameterMode.In) }, ReturnParameters = new[] { FunctionParameter.Create("ReturnType1", modelBlogConceptualType.GetCollectionType(), ParameterMode.ReturnValue) }, EntitySets = new[] { dbModel.ConceptualModel.Container.EntitySets.First(x => x.ElementType == modelBlogConceptualType) } }, null); dbModel.ConceptualModel.Container.AddFunctionImport(getBlogsFuncModel); dbModel.ConceptualToStoreMapping.AddFunctionImportMapping(new FunctionImportMappingComposable( getBlogsFuncModel, getBlogsFunc, new FunctionImportResultMapping(), dbModel.ConceptualToStoreMapping)); var compiledModel = dbModel.Compile(); return(compiledModel); }
private static IList <FunctionParameter> GetStoreReturnParameters(DbModel model, MethodInfo methodInfo, FunctionAttribute functionAttribute) { if (methodInfo.ReturnParameter == null || (methodInfo.ReturnParameter.ParameterType == typeof(void) && functionAttribute.Type != FunctionType.StoredProcedure)) { throw new NotSupportedException(string.Format("The return type of {0} is not supported.", methodInfo.Name)); } var returnParameterAttribute = methodInfo.ReturnParameter.GetCustomAttribute <ParameterAttribute>(); //var returnTypeAttributes = methodInfo.GetCustomAttributes<ResultTypeAttribute>(); if (functionAttribute.Type == FunctionType.StoredProcedure || functionAttribute.Type == FunctionType.TableValuedFunction) { if (returnParameterAttribute != null) { throw new NotSupportedException(string.Format("ParameterAttribute for return value of method {0} is not supported.", methodInfo.Name)); } } if (functionAttribute.Type == FunctionType.StoredProcedure || methodInfo.ReturnType == typeof(void)) { //Stored Procedure return(new FunctionParameter[0]); //return new[] //{ // FunctionParameter.Create("ReturnType", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32), ParameterMode.ReturnValue) //}; } //if (returnTypeAttributes.Length > 0) // throw new NotSupportedException(string.Format("ResultTypeAttribute for method {0} is not supported.", methodInfo.Name)); if (functionAttribute.Type == FunctionType.TableValuedFunction) { //if (returnParameterAttribute != null) // throw new NotSupportedException(string.Format("ParameterAttribute for return value of method {0} is not supported.", methodInfo.Name)); /* * <CollectionType> * <RowType> * <Property Name="PersonID" Type="int" Nullable="false" /> * <Property Name="FirstName" Type="nvarchar" MaxLength="50" /> * <Property Name="LastName" Type="nvarchar" MaxLength="50" /> * <Property Name="JobTitle" Type="nvarchar" MaxLength="50" /> * <Property Name="BusinessEntityType" Type="nvarchar" MaxLength="50" /> * </RowType> * </CollectionType> */ // returnParameterInfo.ParameterType is IQueryable<T>. var storeReturnParameterClrType = methodInfo.ReturnParameter.ParameterType.GetGenericArguments().Single(); var modelReturnParameterStructuralType = GetModelStructualType(model, storeReturnParameterClrType, methodInfo); var modelReturnParameterComplexType = modelReturnParameterStructuralType as ComplexType; RowType storeReturnParameterRowType = null; if (modelReturnParameterComplexType != null) { storeReturnParameterRowType = RowType.Create( modelReturnParameterComplexType.Properties.Select(property => EdmProperty.Create(property.Name, model.ProviderManifest.GetStoreType(property.TypeUsage))), null); } else { var modelReturnParameterEntityType = modelReturnParameterStructuralType as EntityType; if (modelReturnParameterEntityType != null) { storeReturnParameterRowType = RowType.Create( modelReturnParameterEntityType.Properties.Select(property => CloneEdmProperty(property)), null); } else { throw new NotSupportedException(string.Format("Structural type {0} of method {1} cannot be converted to RowType.", modelReturnParameterStructuralType.FullName, methodInfo.Name)); } } return(new[] { FunctionParameter.Create( "ReturnType", storeReturnParameterRowType.GetCollectionType(), // Collection of RowType. ParameterMode.ReturnValue) }); } //if (functionAttribute.Type == FunctionType.NonComposableScalarValuedFunction) //{ // // Non-composable scalar-valued function. // return new FunctionParameter[0]; //} // Composable scalar-valued/Aggregate/Built in/Niladic function. // <Function Name="ufnGetProductListPrice" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="true" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo" // ReturnType ="money"> var storeReturnParameterPrimitiveType = GetStoreParameterPrimitiveType(model, methodInfo, methodInfo.ReturnParameter, functionAttribute); return(new[] { FunctionParameter.Create("ReturnType", storeReturnParameterPrimitiveType, ParameterMode.ReturnValue) }); }
public void Can_create_composable_function_import_with_entity_type_hierarchy() { DbProviderManifest providerManifest; var containerMapping = GetContainerMapping(out providerManifest); var cTypeUsageInt = TypeUsage.Create( PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32), new[] { Facet.Create(MetadataItem.NullableFacetDescription, false) }); var sTypeUsageInt = TypeUsage.Create( providerManifest.GetStoreType(cTypeUsageInt).EdmType, new[] { Facet.Create(MetadataItem.NullableFacetDescription, false) }); var cTypeUsageString = TypeUsage.CreateDefaultTypeUsage( PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String)); var sTypeUsageString = providerManifest.GetStoreType(cTypeUsageString); var itemCollection = containerMapping.StorageMappingItemCollection.EdmItemCollection.GetItems <EntityType>(); var baseEntityType = itemCollection.Single(et => et.Name == "E"); var entityType1 = itemCollection.Single(et => et.Name == "E1"); var entityType2 = itemCollection.Single(et => et.Name == "E2"); var rowType = RowType.Create( new[] { EdmProperty.Create("CId", sTypeUsageInt), EdmProperty.Create("C", sTypeUsageString), EdmProperty.Create("C1", sTypeUsageString), EdmProperty.Create("C2", sTypeUsageString), EdmProperty.Create("CD", sTypeUsageString) }, null); var functionImport = EdmFunction.Create( "F", "N", DataSpace.CSpace, new EdmFunctionPayload { IsComposable = true, ReturnParameters = new[] { FunctionParameter.Create("R", baseEntityType.GetCollectionType(), ParameterMode.ReturnValue) } }, null); var targetFunction = EdmFunction.Create( "SF", "N", DataSpace.SSpace, new EdmFunctionPayload { IsComposable = true, ReturnParameters = new[] { FunctionParameter.Create("R", rowType.GetCollectionType(), ParameterMode.ReturnValue) } }, null); var resultMapping = new FunctionImportResultMapping(); var typeMapping = new FunctionImportEntityTypeMapping( new[] { baseEntityType }, Enumerable.Empty <EntityType>(), new Collection <FunctionImportReturnTypePropertyMapping>() { new FunctionImportReturnTypeScalarPropertyMapping("Id", "CId"), new FunctionImportReturnTypeScalarPropertyMapping("P", "C"), new FunctionImportReturnTypeScalarPropertyMapping("Discriminator", "CD"), }, Enumerable.Empty <FunctionImportEntityTypeMappingConditionValue>()); resultMapping.AddTypeMapping(typeMapping); typeMapping = new FunctionImportEntityTypeMapping( Enumerable.Empty <EntityType>(), new[] { entityType1 }, new Collection <FunctionImportReturnTypePropertyMapping>() { new FunctionImportReturnTypeScalarPropertyMapping("P1", "C1"), }, new [] { new FunctionImportEntityTypeMappingConditionValue("CD", "E1") }); resultMapping.AddTypeMapping(typeMapping); typeMapping = new FunctionImportEntityTypeMapping( Enumerable.Empty <EntityType>(), new[] { entityType2 }, new Collection <FunctionImportReturnTypePropertyMapping>() { new FunctionImportReturnTypeScalarPropertyMapping("P2", "C2"), }, new [] { new FunctionImportEntityTypeMappingConditionValue("CD", "E2") }); resultMapping.AddTypeMapping(typeMapping); var functionImportMapping = new FunctionImportMappingComposable( functionImport, targetFunction, resultMapping, containerMapping); Assert.Same(resultMapping, functionImportMapping.ResultMapping); Assert.Equal(2, functionImportMapping.StructuralTypeMappings.Count); Assert.Equal(1, functionImportMapping.TvfKeys.Length); Assert.Equal(typeof(E1).Name, functionImportMapping.StructuralTypeMappings[0].Item1.Name); Assert.Equal(1, functionImportMapping.StructuralTypeMappings[0].Item2.Count()); Assert.Equal(3, functionImportMapping.StructuralTypeMappings[0].Item3.Count()); Assert.Equal(typeof(E2).Name, functionImportMapping.StructuralTypeMappings[1].Item1.Name); Assert.Equal(1, functionImportMapping.StructuralTypeMappings[0].Item2.Count()); Assert.Equal(3, functionImportMapping.StructuralTypeMappings[0].Item3.Count()); }
private static IList <FunctionParameter> GetStoreReturnParameters( this DbModel model, MethodInfo methodInfo, FunctionAttribute functionAttribute) { ParameterInfo returnParameterInfo = methodInfo.ReturnParameter; if (returnParameterInfo == null || returnParameterInfo.ParameterType == typeof(void)) { throw new NotSupportedException($"The return type of {methodInfo.Name} is not supported."); } ParameterAttribute returnParameterAttribute = returnParameterInfo.GetCustomAttribute <ParameterAttribute>(); ResultTypeAttribute[] returnTypeAttributes = methodInfo.GetCustomAttributes <ResultTypeAttribute>().ToArray(); if (functionAttribute.Type == FunctionType.StoredProcedure) { if (returnParameterAttribute != null) { throw new NotSupportedException( $"{nameof(ParameterAttribute)} for return value of method {methodInfo.Name} is not supported."); } return(new FunctionParameter[0]); } if (returnTypeAttributes.Any()) { throw new NotSupportedException($"{nameof(ResultTypeAttribute)} for method {methodInfo.Name} is not supported."); } if (functionAttribute.Type == FunctionType.TableValuedFunction) { if (returnParameterAttribute != null) { throw new NotSupportedException( $"{nameof(ParameterAttribute)} for return value of method {methodInfo.Name} is not supported."); } /* * <CollectionType> * <RowType> * <Property Name="PersonID" Type="int" Nullable="false" /> * <Property Name="FirstName" Type="nvarchar" MaxLength="50" /> * <Property Name="LastName" Type="nvarchar" MaxLength="50" /> * <Property Name="JobTitle" Type="nvarchar" MaxLength="50" /> * <Property Name="BusinessEntityType" Type="nvarchar" MaxLength="50" /> * </RowType> * </CollectionType> */ // returnParameterInfo.ParameterType is IQueryable<T>. Type storeReturnParameterClrType = returnParameterInfo.ParameterType.GetGenericArguments().Single(); StructuralType modelReturnParameterStructuralType = model.GetModelStructualType( storeReturnParameterClrType, methodInfo); ComplexType modelReturnParameterComplexType = modelReturnParameterStructuralType as ComplexType; RowType storeReturnParameterRowType; if (modelReturnParameterComplexType != null) { storeReturnParameterRowType = RowType.Create( modelReturnParameterComplexType.Properties.Select(property => EdmProperty.Create(property.Name, model.ProviderManifest.GetStoreType(property.TypeUsage))), null); } else { EntityType modelReturnParameterEntityType = modelReturnParameterStructuralType as EntityType; if (modelReturnParameterEntityType != null) { storeReturnParameterRowType = RowType.Create( modelReturnParameterEntityType.Properties.Select(property => { var typeUsage = TypeUsage.Create(model.ProviderManifest.GetStoreType(property.TypeUsage).EdmType, property.TypeUsage.Facets); var result = EdmProperty.Create(property.Name, typeUsage); var propertyNames = new[] { nameof(EdmProperty.Name), nameof(EdmProperty.TypeUsage), nameof(EdmProperty.MetadataProperties) }; result.SetMetadataProperties(property.MetadataProperties.Where(m => !propertyNames.Contains(m.Name))); return(result); }), null); //storeReturnParameterRowType = RowType.Create( // modelReturnParameterEntityType.Properties.Select(property => property.Clone()), // null); } else { throw new NotSupportedException($"Structural type {modelReturnParameterStructuralType.FullName} of method {methodInfo.Name} cannot be converted to {nameof(RowType)}."); } } return(new FunctionParameter[] { FunctionParameter.Create( "ReturnType", storeReturnParameterRowType.GetCollectionType(), // Collection of RowType. ParameterMode.ReturnValue) }); } if (functionAttribute.Type == FunctionType.NonComposableScalarValuedFunction) { // Non-composable scalar-valued function. return(new FunctionParameter[0]); } // Composable scalar-valued/Aggregate/Built in/Niladic function. // <Function Name="ufnGetProductListPrice" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="true" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo" // ReturnType ="money"> PrimitiveType storeReturnParameterPrimitiveType = model.GetStoreParameterPrimitiveType(methodInfo, returnParameterInfo, functionAttribute); return(new FunctionParameter[] { FunctionParameter.Create("ReturnType", storeReturnParameterPrimitiveType, ParameterMode.ReturnValue) }); }
public void Can_create_non_composable_function_with_multiple_results() { DbProviderManifest providerManifest; var containerMapping = GetContainerMapping(out providerManifest); var cTypeUsageInt = TypeUsage.Create( PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32), new[] { Facet.Create(MetadataItem.NullableFacetDescription, false) }); var sTypeUsageInt = TypeUsage.Create( providerManifest.GetStoreType(cTypeUsageInt).EdmType, new[] { Facet.Create(MetadataItem.NullableFacetDescription, false) }); var cTypeUsageString = TypeUsage.CreateDefaultTypeUsage( PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String)); var sTypeUsageString = providerManifest.GetStoreType(cTypeUsageString); var complexType = ComplexType.Create( "RT1", "N", DataSpace.CSpace, new[] { EdmProperty.Create("P1", cTypeUsageInt), EdmProperty.Create("P2", cTypeUsageString) }, null); var entityType = EntityType.Create( "RT2", "N", DataSpace.CSpace, new[] { "P3" }, new[] { EdmProperty.Create("P3", cTypeUsageInt), EdmProperty.Create("P4", cTypeUsageString), }, null); var rowType1 = RowType.Create( new[] { EdmProperty.Create("C1", sTypeUsageInt), EdmProperty.Create("C2", sTypeUsageString) }, null); var rowType2 = RowType.Create( new[] { EdmProperty.Create("C3", sTypeUsageInt), EdmProperty.Create("C4", sTypeUsageString) }, null); var functionImport = EdmFunction.Create( "F", "N", DataSpace.CSpace, new EdmFunctionPayload { IsComposable = false, ReturnParameters = new[] { FunctionParameter.Create("R1", complexType.GetCollectionType(), ParameterMode.ReturnValue), FunctionParameter.Create("R2", entityType.GetCollectionType(), ParameterMode.ReturnValue) }, EntitySets = new[] { new EntitySet(), new EntitySet() } }, null); var targetFunction = EdmFunction.Create( "SF", "N", DataSpace.SSpace, new EdmFunctionPayload { IsComposable = false, ReturnParameters = new[] { FunctionParameter.Create("R1", rowType1.GetCollectionType(), ParameterMode.ReturnValue), FunctionParameter.Create("R2", rowType2.GetCollectionType(), ParameterMode.ReturnValue) }, EntitySets = new [] { new EntitySet(), new EntitySet() } }, null); var resultMappings = new List <FunctionImportResultMapping> { new FunctionImportResultMapping(), new FunctionImportResultMapping() }; resultMappings[0].AddTypeMapping(new FunctionImportComplexTypeMapping( complexType, new Collection <FunctionImportReturnTypePropertyMapping>() { new FunctionImportReturnTypeScalarPropertyMapping("P1", "C1"), new FunctionImportReturnTypeScalarPropertyMapping("P2", "C2"), })); resultMappings[1].AddTypeMapping(new FunctionImportEntityTypeMapping( Enumerable.Empty <EntityType>(), new [] { entityType }, new Collection <FunctionImportReturnTypePropertyMapping>() { new FunctionImportReturnTypeScalarPropertyMapping("P3", "C3"), new FunctionImportReturnTypeScalarPropertyMapping("P4", "C4") }, Enumerable.Empty <FunctionImportEntityTypeMappingCondition>())); var functionImportMapping = new FunctionImportMappingNonComposable( functionImport, targetFunction, resultMappings, containerMapping); Assert.Equal(resultMappings.Count, functionImportMapping.ResultMappings.Count); functionImportMapping.ResultMappings.Each(m => Assert.False(m.IsReadOnly)); functionImportMapping.SetReadOnly(); functionImportMapping.ResultMappings.Each(m => Assert.True(m.IsReadOnly)); }