public void SetReadOnly_is_called_on_child_mapping_items()
        {
            var resultMapping = new FunctionImportResultMapping();

            var entityType = new EntityType("E", "N", DataSpace.CSpace);

            var typeMapping = new FunctionImportEntityTypeMapping(
                Enumerable.Empty <EntityType>(),
                new[] { entityType },
                new Collection <FunctionImportReturnTypePropertyMapping>(),
                Enumerable.Empty <FunctionImportEntityTypeMappingCondition>());

            resultMapping.AddTypeMapping(typeMapping);

            Assert.False(typeMapping.IsReadOnly);
            resultMapping.SetReadOnly();
            Assert.True(typeMapping.IsReadOnly);
        }
        public void SetReadOnly_is_called_on_child_mapping_items()
        {
            var entityType = new EntityType("ET", "N", DataSpace.CSpace);
            var propertyMapping = new FunctionImportReturnTypeScalarPropertyMapping("P", "C");
            var mappingCondition = new FunctionImportEntityTypeMappingConditionIsNull("P", true);
            var mapping
                = new FunctionImportEntityTypeMapping(
                    Enumerable.Empty<EntityType>(),
                    new[] { entityType },
                    new Collection<FunctionImportReturnTypePropertyMapping> { propertyMapping },
                    new[] { mappingCondition });

            Assert.False(propertyMapping.IsReadOnly);
            Assert.False(mappingCondition.IsReadOnly);
            mapping.SetReadOnly();
            Assert.True(propertyMapping.IsReadOnly);
            Assert.True(mappingCondition.IsReadOnly);
        }
        public void Cannot_add_type_mapping_if_read_only()
        {
            var resultMapping = new FunctionImportResultMapping();

            var entityType = new EntityType("E", "N", DataSpace.CSpace);

            var typeMapping = new FunctionImportEntityTypeMapping(
                Enumerable.Empty<EntityType>(),
                new[] { entityType },
                new Collection<FunctionImportReturnTypePropertyMapping>(),
                Enumerable.Empty<FunctionImportEntityTypeMappingCondition>());

            resultMapping.SetReadOnly();

            Assert.Equal(
                Strings.OperationOnReadOnlyItem,
                Assert.Throws<InvalidOperationException>(
                    () => resultMapping.AddTypeMapping(typeMapping)).Message);
        }
        public void Cannot_add_type_mapping_if_read_only()
        {
            var resultMapping = new FunctionImportResultMapping();

            var entityType = new EntityType("E", "N", DataSpace.CSpace);

            var typeMapping = new FunctionImportEntityTypeMapping(
                Enumerable.Empty <EntityType>(),
                new[] { entityType },
                new Collection <FunctionImportReturnTypePropertyMapping>(),
                Enumerable.Empty <FunctionImportEntityTypeMappingCondition>());

            resultMapping.SetReadOnly();

            Assert.Equal(
                Strings.OperationOnReadOnlyItem,
                Assert.Throws <InvalidOperationException>(
                    () => resultMapping.AddTypeMapping(typeMapping)).Message);
        }
        public void SetReadOnly_is_called_on_child_mapping_items()
        {
            var entityType       = new EntityType("ET", "N", DataSpace.CSpace);
            var propertyMapping  = new FunctionImportReturnTypeScalarPropertyMapping("P", "C");
            var mappingCondition = new FunctionImportEntityTypeMappingConditionIsNull("P", true);
            var mapping
                = new FunctionImportEntityTypeMapping(
                      Enumerable.Empty <EntityType>(),
                      new[] { entityType },
                      new Collection <FunctionImportReturnTypePropertyMapping> {
                propertyMapping
            },
                      new[] { mappingCondition });

            Assert.False(propertyMapping.IsReadOnly);
            Assert.False(mappingCondition.IsReadOnly);
            mapping.SetReadOnly();
            Assert.True(propertyMapping.IsReadOnly);
            Assert.True(mappingCondition.IsReadOnly);
        }
        public void Can_add_get_remove_type_mapping()
        {
            var resultMapping = new FunctionImportResultMapping();

            Assert.Empty(resultMapping.TypeMappings);

            var entityType = new EntityType("E", "N", DataSpace.CSpace);

            var typeMapping = new FunctionImportEntityTypeMapping(
                Enumerable.Empty<EntityType>(),
                new[] { entityType },
                new Collection<FunctionImportReturnTypePropertyMapping>(),
                Enumerable.Empty<FunctionImportEntityTypeMappingCondition>());

            resultMapping.AddTypeMapping(typeMapping);
            
            Assert.Equal(1, resultMapping.TypeMappings.Count);
            Assert.Same(typeMapping, resultMapping.TypeMappings[0]);

            resultMapping.RemoveTypeMapping(typeMapping);

            Assert.Empty(resultMapping.TypeMappings);
        }
        public void Can_add_get_remove_type_mapping()
        {
            var resultMapping = new FunctionImportResultMapping();

            Assert.Empty(resultMapping.TypeMappings);

            var entityType = new EntityType("E", "N", DataSpace.CSpace);

            var typeMapping = new FunctionImportEntityTypeMapping(
                Enumerable.Empty <EntityType>(),
                new[] { entityType },
                new Collection <FunctionImportReturnTypePropertyMapping>(),
                Enumerable.Empty <FunctionImportEntityTypeMappingCondition>());

            resultMapping.AddTypeMapping(typeMapping);

            Assert.Equal(1, resultMapping.TypeMappings.Count);
            Assert.Same(typeMapping, resultMapping.TypeMappings[0]);

            resultMapping.RemoveTypeMapping(typeMapping);

            Assert.Empty(resultMapping.TypeMappings);
        }
        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());
        }
        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 CreateFunctionImportEntityTypeMappingTypeName_returns_correct_TypeName_attribute_value()
        {
            var ofEntityTypes = new[]
            {
                new EntityType("OfType1", "Ns", DataSpace.CSpace),
                new EntityType("OfType2", "Ns", DataSpace.CSpace)
            };

            var entityTypes = new[]
            {
                new EntityType("ET1", "Ns", DataSpace.CSpace),
                new EntityType("ET2", "Ns", DataSpace.CSpace)
            };

            var mapping = new FunctionImportEntityTypeMapping(
                ofEntityTypes,
                entityTypes,
                new Collection<FunctionImportReturnTypePropertyMapping>(),
                new List<FunctionImportEntityTypeMappingCondition>());

            Assert.Equal(
                "Ns.ET1;Ns.ET2;IsTypeOf(Ns.OfType1);IsTypeOf(Ns.OfType2)",
                MslXmlSchemaWriter.CreateFunctionImportEntityTypeMappingTypeName(mapping));
        }
        public void SetReadOnly_is_called_on_child_mapping_items()
        {
            var resultMapping = new FunctionImportResultMapping();

            var entityType = new EntityType("E", "N", DataSpace.CSpace);

            var typeMapping = new FunctionImportEntityTypeMapping(
                Enumerable.Empty<EntityType>(),
                new[] { entityType },
                new Collection<FunctionImportReturnTypePropertyMapping>(),
                Enumerable.Empty<FunctionImportEntityTypeMappingCondition>());

            resultMapping.AddTypeMapping(typeMapping);

            Assert.False(typeMapping.IsReadOnly);
            resultMapping.SetReadOnly();
            Assert.True(typeMapping.IsReadOnly);
        }
        // internal for testing
        internal static string CreateFunctionImportEntityTypeMappingTypeName(FunctionImportEntityTypeMapping entityTypeMapping)
        {
            var entityTypeName =
                string.Join(
                    ";",
                    entityTypeMapping.EntityTypes.Select(e => GetEntityTypeName(e.FullName, false))
                        .Concat(entityTypeMapping.IsOfTypeEntityTypes.Select(e => GetEntityTypeName(e.FullName, true))));

            return entityTypeName;
        }
        private void WriteFunctionImportEntityTypeMappingElement(FunctionImportEntityTypeMapping entityTypeMapping)
        {
            DebugCheck.NotNull(entityTypeMapping);

            _xmlWriter.WriteStartElement(MslConstructs.EntityTypeMappingElement);

            var entityTypeName = CreateFunctionImportEntityTypeMappingTypeName(entityTypeMapping);

            _xmlWriter.WriteAttributeString(MslConstructs.EntityTypeMappingTypeNameAttribute, entityTypeName);

            WriteFunctionImportPropertyMappingElements(
                entityTypeMapping.PropertyMappings.Cast<FunctionImportReturnTypeScalarPropertyMapping>());

            foreach (var condition in entityTypeMapping.Conditions)
            {
                WriteFunctionImportConditionElement(condition);
            }

            _xmlWriter.WriteEndElement();
        }
        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());
        }
        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);
        }