public void Configure_should_call_configure_function_configurations()
        {
            var modificationFunctionsConfiguration = new ModificationStoredProceduresConfiguration();

            var mockModificationFunctionConfiguration = new Mock<ModificationStoredProcedureConfiguration>();

            modificationFunctionsConfiguration.Insert(mockModificationFunctionConfiguration.Object);
            modificationFunctionsConfiguration.Update(mockModificationFunctionConfiguration.Object);
            modificationFunctionsConfiguration.Delete(mockModificationFunctionConfiguration.Object);

            var entitySet = new EntitySet();
            entitySet.ChangeEntityContainerWithoutCollectionFixup(new EntityContainer("C", DataSpace.CSpace));

            var storageModificationFunctionMapping
                = new ModificationFunctionMapping(
                    entitySet,
                    new EntityType("E", "N", DataSpace.CSpace),
                    new EdmFunction("F", "N", DataSpace.SSpace),
                    new ModificationFunctionParameterBinding[0],
                    null,
                    null);

            modificationFunctionsConfiguration.Configure(
                new EntityTypeModificationFunctionMapping(
                    new EntityType("E", "N", DataSpace.CSpace),
                    storageModificationFunctionMapping,
                    storageModificationFunctionMapping,
                    storageModificationFunctionMapping),
                ProviderRegistry.Sql2008_ProviderManifest);

            mockModificationFunctionConfiguration
                .Verify(
                    m => m.Configure(storageModificationFunctionMapping, It.IsAny<DbProviderManifest>()),
                    Times.Exactly(3));
        }
        public void PrimaryParameterBindings_should_omit_original_value_parameters_when_update()
        {
            var entitySet = new EntitySet();
            entitySet.ChangeEntityContainerWithoutCollectionFixup(new EntityContainer("C", DataSpace.CSpace));

            var storageModificationFunctionMapping
                = new ModificationFunctionMapping(
                    entitySet,
                    new EntityType("E", "N", DataSpace.CSpace),
                    new EdmFunction("F", "N", DataSpace.SSpace),
                    new[]
                        {
                            new ModificationFunctionParameterBinding(
                                new FunctionParameter(),
                                new ModificationFunctionMemberPath(
                                new EdmMember[]
                                    {
                                        new EdmProperty("M")
                                    },
                                null),
                                false)
                        },
                    null,
                    null);

            var storageEntityTypeModificationFunctionMapping
                = new EntityTypeModificationFunctionMapping(
                    new EntityType("E", "N", DataSpace.CSpace),
                    storageModificationFunctionMapping,
                    storageModificationFunctionMapping,
                    storageModificationFunctionMapping);

            Assert.Equal(2, storageEntityTypeModificationFunctionMapping.PrimaryParameterBindings.Count());
        }
        public void Can_clear_modification_function_mappings()
        {
            var entityType = new EntityType("E", "N", DataSpace.CSpace);
            var entitySet = new EntitySet("S", "N", null, null, entityType);
            var function = new EdmFunction("F", "N", DataSpace.SSpace, new EdmFunctionPayload());

            var container = new EntityContainer("C", DataSpace.CSpace);
            container.AddEntitySetBase(entitySet);

            var entitySetMapping =
                new EntitySetMapping(
                    entitySet,
                    new EntityContainerMapping(container));

            var functionMapping =
                new ModificationFunctionMapping(
                    entitySet,
                    entityType,
                    function,
                    Enumerable.Empty<ModificationFunctionParameterBinding>(),
                    null,
                    null);

            var entityFunctionMappings =
                new EntityTypeModificationFunctionMapping(entityType, functionMapping, null, null);

            entitySetMapping.AddModificationFunctionMapping(entityFunctionMappings);

            Assert.Equal(1, entitySetMapping.ModificationFunctionMappings.Count());

            entitySetMapping.ClearModificationFunctionMappings();

            Assert.Equal(0, entitySetMapping.ModificationFunctionMappings.Count());
        }
        /// <summary>
        /// Initalizes a new AssociationSetModificationFunctionMapping instance.
        /// </summary>
        /// <param name="associationSet">An association set.</param>
        /// <param name="deleteFunctionMapping">A delete function mapping.</param>
        /// <param name="insertFunctionMapping">An insert function mapping.</param>
        public AssociationSetModificationFunctionMapping(
            AssociationSet associationSet,
            ModificationFunctionMapping deleteFunctionMapping,
            ModificationFunctionMapping insertFunctionMapping)
        {
            Check.NotNull(associationSet, "associationSet");

            _associationSet = associationSet;
            _deleteFunctionMapping = deleteFunctionMapping;
            _insertFunctionMapping = insertFunctionMapping;
        }
        /// <summary>
        /// Initializes a new EntityTypeModificationFunctionMapping instance.
        /// </summary>
        /// <param name="entityType">An entity type.</param>
        /// <param name="deleteFunctionMapping">A delete function mapping.</param>
        /// <param name="insertFunctionMapping">An insert function mapping.</param>
        /// <param name="updateFunctionMapping">An updated function mapping.</param>
        public EntityTypeModificationFunctionMapping(
            EntityType entityType,
            ModificationFunctionMapping deleteFunctionMapping,
            ModificationFunctionMapping insertFunctionMapping,
            ModificationFunctionMapping updateFunctionMapping)
        {
            Check.NotNull(entityType, "entityType");

            _entityType = entityType;
            _deleteFunctionMapping = deleteFunctionMapping;
            _insertFunctionMapping = insertFunctionMapping;
            _updateFunctionMapping = updateFunctionMapping;
        }
        public void WriteEntitySetMappingElement_should_write_modification_function_mappings()
        {
            var fixture = new Fixture();

            var entityType = new EntityType("E", "N", DataSpace.CSpace);
            var entitySet = new EntitySet("ES", "S", null, null, entityType);
            var entityContainer = new EntityContainer("EC", DataSpace.SSpace);

            entityContainer.AddEntitySetBase(entitySet);

            var storageEntitySetMapping
                = new EntitySetMapping(
                    entitySet,
                    new EntityContainerMapping(entityContainer));

            var storageModificationFunctionMapping
                = new ModificationFunctionMapping(
                    entitySet,
                    entityType,
                    new EdmFunction("F", "N", DataSpace.SSpace, new EdmFunctionPayload()),
                    Enumerable.Empty<ModificationFunctionParameterBinding>(),
                    null,
                    null);

            storageEntitySetMapping.AddModificationFunctionMapping(
                new EntityTypeModificationFunctionMapping(
                    entityType,
                    storageModificationFunctionMapping,
                    storageModificationFunctionMapping,
                    storageModificationFunctionMapping));

            fixture.Writer.WriteEntitySetMappingElement(storageEntitySetMapping);

            Assert.Equal(
                @"<EntitySetMapping Name=""ES"">
  <EntityTypeMapping TypeName="".E"">
    <ModificationFunctionMapping>
      <InsertFunction FunctionName=""N.F"" />
      <UpdateFunction FunctionName=""N.F"" />
      <DeleteFunction FunctionName=""N.F"" />
    </ModificationFunctionMapping>
  </EntityTypeMapping>
</EntitySetMapping>",
                fixture.ToString());
        }
        public void Can_retrieve_properties()
        {
            var entityType = new EntityType("ET", "N", DataSpace.CSpace);
            var entitySet = new EntitySet("ES", "S", "T", "Q", entityType);
            var entityContainer = new EntityContainer("EC", DataSpace.SSpace);

            entityContainer.AddEntitySetBase(entitySet);

            var function = new EdmFunction("F", "N", DataSpace.SSpace, new EdmFunctionPayload());
            var parameterBindings
                = new[]
                  {
                      new ModificationFunctionParameterBinding(
                          new FunctionParameter(), 
                          new ModificationFunctionMemberPath(Enumerable.Empty<EdmMember>(), null),
                          true)
                  };
            var rowsAffectedParameter = new FunctionParameter("rows_affected", new TypeUsage(), ParameterMode.Out);

            var resultBindings
                = new[]
                  {
                      new ModificationFunctionResultBinding(
                          "C", 
                          EdmProperty.CreatePrimitive(
                              "P", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String)))
                  };

            var mapping
                = new ModificationFunctionMapping(
                    entitySet, entityType, function,
                    parameterBindings, rowsAffectedParameter, resultBindings);

            Assert.Same(rowsAffectedParameter, mapping.RowsAffectedParameter);
            Assert.Same(function, mapping.Function);
            Assert.Equal(parameterBindings, mapping.ParameterBindings);
            Assert.Equal(resultBindings, mapping.ResultBindings);
        }
        private void ConfigureName(ModificationFunctionMapping modificationStoredProcedureMapping)
        {
            DebugCheck.NotNull(modificationStoredProcedureMapping);

            if (!string.IsNullOrWhiteSpace(_name))
            {
                modificationStoredProcedureMapping.Function.StoreFunctionNameAttribute = _name;
            }
        }
        public void WriteFunctionMapping(
            string functionElement, ModificationFunctionMapping functionMapping, bool associationSetMapping = false)
        {
            DebugCheck.NotNull(functionMapping);

            _xmlWriter.WriteStartElement(functionElement);
            _xmlWriter.WriteAttributeString(MslConstructs.FunctionNameAttribute, functionMapping.Function.FullName);

            if (functionMapping.RowsAffectedParameter != null)
            {
                _xmlWriter.WriteAttributeString(
                    MslConstructs.RowsAffectedParameterAttribute,
                    functionMapping.RowsAffectedParameter.Name);
            }

            if (!associationSetMapping)
            {
                WritePropertyParameterBindings(functionMapping.ParameterBindings);
                WriteAssociationParameterBindings(functionMapping.ParameterBindings);

                if (functionMapping.ResultBindings != null)
                {
                    WriteResultBindings(functionMapping.ResultBindings);
                }
            }
            else
            {
                WriteAssociationSetMappingParameterBindings(functionMapping.ParameterBindings);
            }

            _xmlWriter.WriteEndElement();
        }
示例#10
0
        public void Can_retrieve_properties_and_set_read_only()
        {
            var entitySet = new EntitySet();

            entitySet.ChangeEntityContainerWithoutCollectionFixup(new EntityContainer("C", DataSpace.CSpace));

            var deleteModificationFunctionMapping
                = new ModificationFunctionMapping(
                      entitySet,
                      new EntityType("E", "N", DataSpace.CSpace),
                      new EdmFunction("F", "N", DataSpace.SSpace),
                      new[]
            {
                new ModificationFunctionParameterBinding(
                    new FunctionParameter(),
                    new ModificationFunctionMemberPath(
                        new EdmMember[]
                {
                    new EdmProperty("M")
                },
                        null),
                    false)
            },
                      null,
                      null);

            var insertModificationFunctionMapping
                = new ModificationFunctionMapping(
                      entitySet,
                      new EntityType("E", "N", DataSpace.CSpace),
                      new EdmFunction("F", "N", DataSpace.SSpace),
                      new[]
            {
                new ModificationFunctionParameterBinding(
                    new FunctionParameter(),
                    new ModificationFunctionMemberPath(
                        new EdmMember[]
                {
                    new EdmProperty("M")
                },
                        null),
                    false)
            },
                      null,
                      null);

            var updateModificationFunctionMapping
                = new ModificationFunctionMapping(
                      entitySet,
                      new EntityType("E", "N", DataSpace.CSpace),
                      new EdmFunction("F", "N", DataSpace.SSpace),
                      new[]
            {
                new ModificationFunctionParameterBinding(
                    new FunctionParameter(),
                    new ModificationFunctionMemberPath(
                        new EdmMember[]
                {
                    new EdmProperty("M")
                },
                        null),
                    false)
            },
                      null,
                      null);

            var entityType = new EntityType("E", "N", DataSpace.CSpace);
            var entityTypeModificationFunctionMapping
                = new EntityTypeModificationFunctionMapping(
                      entityType,
                      deleteModificationFunctionMapping,
                      insertModificationFunctionMapping,
                      updateModificationFunctionMapping);

            Assert.Same(entityTypeModificationFunctionMapping.EntityType, entityType);
            Assert.Same(entityTypeModificationFunctionMapping.DeleteFunctionMapping, deleteModificationFunctionMapping);
            Assert.Same(entityTypeModificationFunctionMapping.InsertFunctionMapping, insertModificationFunctionMapping);
            Assert.Same(entityTypeModificationFunctionMapping.UpdateFunctionMapping, updateModificationFunctionMapping);

            Assert.False(entityTypeModificationFunctionMapping.IsReadOnly);
            Assert.False(deleteModificationFunctionMapping.IsReadOnly);
            Assert.False(insertModificationFunctionMapping.IsReadOnly);
            Assert.False(updateModificationFunctionMapping.IsReadOnly);

            entityTypeModificationFunctionMapping.SetReadOnly();

            Assert.True(entityTypeModificationFunctionMapping.IsReadOnly);
            Assert.True(deleteModificationFunctionMapping.IsReadOnly);
            Assert.True(insertModificationFunctionMapping.IsReadOnly);
            Assert.True(updateModificationFunctionMapping.IsReadOnly);
        }
示例#11
0
        private static void UniquifyFunctionName(
            DbDatabaseMapping databaseMapping,
            ModificationStoredProcedureConfiguration modificationStoredProcedureConfiguration,
            ModificationFunctionMapping functionMapping)
        {
            DebugCheck.NotNull(databaseMapping);
            DebugCheck.NotNull(functionMapping);

            if ((modificationStoredProcedureConfiguration == null)
                || string.IsNullOrWhiteSpace(modificationStoredProcedureConfiguration.Name))
            {
                functionMapping.Function.StoreFunctionNameAttribute
                    = databaseMapping.Database.Functions.Except(new[] { functionMapping.Function })
                                     .Select(f => f.FunctionName)
                                     .Uniquify(functionMapping.Function.FunctionName);
            }
        }
        public void WriteAssociationSetMapping_should_write_modification_function_mapping()
        {
            var fixture = new Fixture();

            var entityType = new EntityType("E", "N", DataSpace.CSpace);
            var entitySet = new EntitySet("ES", "S", null, null, entityType);
            new EntityContainer("EC", DataSpace.SSpace).AddEntitySetBase(entitySet);
            var associationSet = new AssociationSet("AS", new AssociationType("A", XmlConstants.ModelNamespace_3, false, DataSpace.CSpace));

            var associationEndMember1 = new AssociationEndMember("Source", new EntityType("E", "N", DataSpace.CSpace));
            associationSet.AddAssociationSetEnd(new AssociationSetEnd(entitySet, associationSet, associationEndMember1));

            var associationEndMember2 = new AssociationEndMember("Target", new EntityType("E", "N", DataSpace.CSpace));
            associationSet.AddAssociationSetEnd(new AssociationSetEnd(entitySet, associationSet, associationEndMember2));

            var storageModificationFunctionMapping
                = new ModificationFunctionMapping(
                    associationSet,
                    associationSet.ElementType,
                    new EdmFunction("F", "N", DataSpace.SSpace, new EdmFunctionPayload()),
                    new[]
                        {
                            new ModificationFunctionParameterBinding(
                                new FunctionParameter(
                                "P",
                                TypeUsage.Create(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32)),
                                ParameterMode.In),
                                new ModificationFunctionMemberPath(
                                new EdmMember[]
                                    {
                                        new EdmProperty("K"),
                                        associationEndMember1
                                    },
                                associationSet),
                                true),
                            new ModificationFunctionParameterBinding(
                                new FunctionParameter(
                                "P",
                                TypeUsage.Create(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32)),
                                ParameterMode.In),
                                new ModificationFunctionMemberPath(
                                new EdmMember[]
                                    {
                                        new EdmProperty("K"),
                                        associationEndMember2
                                    },
                                associationSet),
                                false)
                        },
                    null,
                    null);

            var associationSetMapping
                = new AssociationSetMapping(
                    associationSet,
                    entitySet)
                      {
                          SourceEndMapping
                              = new EndPropertyMapping
                                    {
                                        AssociationEnd = associationEndMember1
                                    },
                          TargetEndMapping
                              = new EndPropertyMapping
                                    {
                                        AssociationEnd = associationEndMember2
                                    },
                          ModificationFunctionMapping = new AssociationSetModificationFunctionMapping(
                              associationSet,
                              storageModificationFunctionMapping,
                              storageModificationFunctionMapping)
                      };

            fixture.Writer.WriteAssociationSetMappingElement(associationSetMapping);

            Assert.Equal(
                @"<AssociationSetMapping Name=""AS"" TypeName="".A"" StoreEntitySet=""E"">
  <EndProperty Name=""Source"" />
  <EndProperty Name=""Target"" />
  <ModificationFunctionMapping>
    <InsertFunction FunctionName=""N.F"">
      <EndProperty Name=""Source"">
        <ScalarProperty Name=""K"" ParameterName=""P"" Version=""Current"" />
      </EndProperty>
      <EndProperty Name=""Target"">
        <ScalarProperty Name=""K"" ParameterName=""P"" Version=""Original"" />
      </EndProperty>
    </InsertFunction>
    <DeleteFunction FunctionName=""N.F"">
      <EndProperty Name=""Source"">
        <ScalarProperty Name=""K"" ParameterName=""P"" Version=""Current"" />
      </EndProperty>
      <EndProperty Name=""Target"">
        <ScalarProperty Name=""K"" ParameterName=""P"" Version=""Original"" />
      </EndProperty>
    </DeleteFunction>
  </ModificationFunctionMapping>
</AssociationSetMapping>",
                fixture.ToString());
        }
        private void ConfigureResultBindings(ModificationFunctionMapping modificationStoredProcedureMapping)
        {
            DebugCheck.NotNull(modificationStoredProcedureMapping);

            foreach (var keyValue in _resultBindings)
            {
                var propertyInfo = keyValue.Key;
                var columnName = keyValue.Value;

                var resultBinding
                    = (modificationStoredProcedureMapping
                           .ResultBindings ?? Enumerable.Empty<ModificationFunctionResultBinding>())
                        .SingleOrDefault(rb => propertyInfo.IsSameAs(rb.Property.GetClrPropertyInfo()));

                if (resultBinding == null)
                {
                    throw Error.ResultBindingNotFound(
                        propertyInfo.Name,
                        modificationStoredProcedureMapping.Function.FunctionName);
                }

                resultBinding.ColumnName = columnName;
            }
        }
        public void WriteFunctionMapping_should_write_simple_parameter_and_result_bindings_and_rows_affected_parameter()
        {
            var fixture = new Fixture();

            var entityType = new EntityType("E", "N", DataSpace.CSpace);
            var entitySet = new EntitySet("ES", "S", null, null, entityType);
            new EntityContainer("EC", DataSpace.SSpace).AddEntitySetBase(entitySet);

            var property = new EdmProperty("M");

            var typeUsage = TypeUsage.Create(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32));

            var storageModificationFunctionMapping
                = new ModificationFunctionMapping(
                    entitySet,
                    entityType,
                    new EdmFunction("F", "N", DataSpace.SSpace, new EdmFunctionPayload()),
                    new[]
                        {
                            new ModificationFunctionParameterBinding(
                                new FunctionParameter(
                                "P",
                                typeUsage,
                                ParameterMode.In),
                                new ModificationFunctionMemberPath(
                                new[] { property },
                                null),
                                true),
                            new ModificationFunctionParameterBinding(
                                new FunctionParameter(
                                "P_Original",
                                typeUsage,
                                ParameterMode.In),
                                new ModificationFunctionMemberPath(
                                new[] { property },
                                null),
                                false)
                        },
                    new FunctionParameter("RowsAffected", typeUsage, ParameterMode.Out),
                    new[]
                        {
                            new ModificationFunctionResultBinding("C", property)
                        });

            fixture.Writer.WriteFunctionMapping("InsertFunction", storageModificationFunctionMapping);

            Assert.Equal(
                @"<InsertFunction FunctionName=""N.F"" RowsAffectedParameter=""RowsAffected"">
  <ScalarProperty Name=""M"" ParameterName=""P"" Version=""Current"" />
  <ScalarProperty Name=""M"" ParameterName=""P_Original"" Version=""Original"" />
  <ResultBinding Name=""M"" ColumnName=""C"" />
</InsertFunction>",
                fixture.ToString());
        }
        public void WriteFunctionMapping_should_write_complex_parameter_bindings()
        {
            var fixture = new Fixture();

            var entityType = new EntityType("E", "N", DataSpace.CSpace);
            var entitySet = new EntitySet("ES", "S", null, null, entityType);
            new EntityContainer("EC", DataSpace.SSpace).AddEntitySetBase(entitySet);

            var storageModificationFunctionMapping
                = new ModificationFunctionMapping(
                    entitySet,
                    entityType,
                    new EdmFunction("F", "N", DataSpace.SSpace, new EdmFunctionPayload()),
                    new[]
                        {
                            new ModificationFunctionParameterBinding(
                                new FunctionParameter(
                                "P",
                                TypeUsage.Create(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32)),
                                ParameterMode.In),
                                new ModificationFunctionMemberPath(
                                new[]
                                    {
                                        EdmProperty.CreateComplex("C1", new ComplexType()),
                                        EdmProperty.CreateComplex("C2", new ComplexType()),
                                        new EdmProperty("M")
                                    },
                                null),
                                true)
                        },
                    null,
                    null);

            fixture.Writer.WriteFunctionMapping("InsertFunction", storageModificationFunctionMapping);

            Assert.Equal(
                @"<InsertFunction FunctionName=""N.F"">
  <ComplexProperty Name=""C1"" TypeName=""."">
    <ComplexProperty Name=""C2"" TypeName=""."">
      <ScalarProperty Name=""M"" ParameterName=""P"" Version=""Current"" />
    </ComplexProperty>
  </ComplexProperty>
</InsertFunction>",
                fixture.ToString());
        }
        public void Can_add_get_remove_modification_function_mappings()
        {
            var entityType = new EntityType("E", "N", DataSpace.CSpace);
            var entitySet = new EntitySet("S", "N", null, null, entityType);
            var function = new EdmFunction(
                "F", "N", DataSpace.CSpace,
                new EdmFunctionPayload
                    {
                        IsFunctionImport = true
                    });

            var container = new EntityContainer("C", DataSpace.CSpace);
            container.AddEntitySetBase(entitySet);
            container.AddFunctionImport(function);

            var entitySetMapping =
                new EntitySetMapping(
                    entitySet,
                    new EntityContainerMapping(container));

            var functionMapping =
                new ModificationFunctionMapping(
                    entitySet,
                    entityType,
                    function,
                    Enumerable.Empty<ModificationFunctionParameterBinding>(),
                    null,
                    null);

            var entityFunctionMappings =
                new EntityTypeModificationFunctionMapping(entityType, functionMapping, null, null);

            entitySetMapping.AddModificationFunctionMapping(entityFunctionMappings);

            Assert.Same(entityFunctionMappings, entitySetMapping.ModificationFunctionMappings.Single());

            entitySetMapping.RemoveModificationFunctionMapping(entityFunctionMappings);

            Assert.Empty(entitySetMapping.ModificationFunctionMappings);
        }
        public void SetReadOnly_is_called_on_child_mapping_items()
        {
            var entityType = new EntityType("ET", "N", DataSpace.CSpace);
            var entitySet = new EntitySet("ES", "S", "T", "Q", entityType);
            var entityContainer = new EntityContainer("EC", DataSpace.SSpace);

            entityContainer.AddEntitySetBase(entitySet);

            var function = new EdmFunction("F", "N", DataSpace.SSpace, new EdmFunctionPayload());
            var parameterBindings
                = new[]
                  {
                      new ModificationFunctionParameterBinding(
                          new FunctionParameter(), 
                          new ModificationFunctionMemberPath(Enumerable.Empty<EdmMember>(), null),
                          true)
                  };
            var rowsAffectedParameter = new FunctionParameter("rows_affected", new TypeUsage(), ParameterMode.Out);

            var resultBindings
                = new[]
                  {
                      new ModificationFunctionResultBinding(
                          "C", 
                          EdmProperty.CreatePrimitive(
                              "P", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String)))
                  };

            var mapping
                = new ModificationFunctionMapping(
                    entitySet, entityType, function,
                    parameterBindings, rowsAffectedParameter, resultBindings);

            Assert.False(mapping.IsReadOnly);
            parameterBindings.Each(b => Assert.False(b.IsReadOnly));
            resultBindings.Each(b => Assert.False(b.IsReadOnly));
            mapping.SetReadOnly();
            Assert.True(mapping.IsReadOnly);
            parameterBindings.Each(b => Assert.True(b.IsReadOnly));
            resultBindings.Each(b => Assert.True(b.IsReadOnly));
        }
        private void ConfigureRowsAffectedParameter(
            ModificationFunctionMapping modificationStoredProcedureMapping, DbProviderManifest providerManifest)
        {
            DebugCheck.NotNull(modificationStoredProcedureMapping);
            DebugCheck.NotNull(providerManifest);

            if (!string.IsNullOrWhiteSpace(_rowsAffectedParameter))
            {
                if (modificationStoredProcedureMapping.RowsAffectedParameter == null)
                {
                    var rowsAffectedParameter
                        = new FunctionParameter(
                            "_RowsAffected_",
                            providerManifest.GetStoreType(
                                TypeUsage.CreateDefaultTypeUsage(
                                    PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32))),
                            ParameterMode.Out);

                    modificationStoredProcedureMapping.Function.AddParameter(rowsAffectedParameter);
                    modificationStoredProcedureMapping.RowsAffectedParameter = rowsAffectedParameter;
                }

                modificationStoredProcedureMapping.RowsAffectedParameter.Name = _rowsAffectedParameter;

                _configuredParameters.Add(modificationStoredProcedureMapping.RowsAffectedParameter);
            }
        }
        public void SetReadOnly_is_called_on_child_mapping_items()
        {
            var entityType = new EntityType("E", "N", DataSpace.CSpace);
            var entitySet = new EntitySet("S", "N", null, null, entityType);
            var function = new EdmFunction(
                "F", "N", DataSpace.CSpace,
                new EdmFunctionPayload
                {
                    IsFunctionImport = true
                });

            var container = new EntityContainer("C", DataSpace.CSpace);
            container.AddEntitySetBase(entitySet);
            container.AddFunctionImport(function);

            var entitySetMapping =
                new EntitySetMapping(
                    entitySet,
                    new EntityContainerMapping(container));

            var functionMapping =
                new ModificationFunctionMapping(
                    entitySet,
                    entityType,
                    function,
                    Enumerable.Empty<ModificationFunctionParameterBinding>(),
                    null,
                    null);

            var entityFunctionMapping =
                new EntityTypeModificationFunctionMapping(entityType, functionMapping, null, null);

            entitySetMapping.AddModificationFunctionMapping(entityFunctionMapping);

            var entityTypeMapping = new EntityTypeMapping(entitySetMapping);

            entitySetMapping.AddTypeMapping(entityTypeMapping);

            Assert.False(entityTypeMapping.IsReadOnly);
            Assert.False(entityFunctionMapping.IsReadOnly);
            entitySetMapping.SetReadOnly();
            Assert.True(entityTypeMapping.IsReadOnly);
            Assert.True(entityFunctionMapping.IsReadOnly);
        }
        public void Cannot_remove_modification_function_mapping_when_read_only()
        {
            var entityType = new EntityType("E", "N", DataSpace.CSpace);
            var entitySet = new EntitySet("S", "N", null, null, entityType);
            var function = new EdmFunction(
                "F", "N", DataSpace.CSpace,
                new EdmFunctionPayload
                {
                    IsFunctionImport = true
                });

            var container = new EntityContainer("C", DataSpace.CSpace);
            container.AddEntitySetBase(entitySet);
            container.AddFunctionImport(function);

            var entitySetMapping =
                new EntitySetMapping(
                    entitySet,
                    new EntityContainerMapping(container));

            var functionMapping =
                new ModificationFunctionMapping(
                    entitySet,
                    entityType,
                    function,
                    Enumerable.Empty<ModificationFunctionParameterBinding>(),
                    null,
                    null);

            var entityFunctionMappings =
                new EntityTypeModificationFunctionMapping(entityType, functionMapping, null, null);

            entitySetMapping.AddModificationFunctionMapping(entityFunctionMappings);
            entitySetMapping.SetReadOnly();

            Assert.Equal(
                Strings.OperationOnReadOnlyItem,
                Assert.Throws<InvalidOperationException>(
                    () => entitySetMapping.RemoveModificationFunctionMapping(entityFunctionMappings)).Message);
        }
        public virtual void Configure(
            ModificationFunctionMapping modificationStoredProcedureMapping, DbProviderManifest providerManifest)
        {
            DebugCheck.NotNull(modificationStoredProcedureMapping);
            DebugCheck.NotNull(providerManifest);

            _configuredParameters = new List<FunctionParameter>();

            ConfigureName(modificationStoredProcedureMapping);
            ConfigureSchema(modificationStoredProcedureMapping);
            ConfigureRowsAffectedParameter(modificationStoredProcedureMapping, providerManifest);
            ConfigureParameters(modificationStoredProcedureMapping);
            ConfigureResultBindings(modificationStoredProcedureMapping);
        }
        public void Configure_should_introduce_rows_affected_parameter_when_configured()
        {
            var modificationFunctionConfiguration = new ModificationStoredProcedureConfiguration();

            modificationFunctionConfiguration.RowsAffectedParameter("rows_affected");

            var entitySet = new EntitySet();
            entitySet.ChangeEntityContainerWithoutCollectionFixup(new EntityContainer("C", DataSpace.CSpace));

            var storageModificationFunctionMapping 
                = new ModificationFunctionMapping(
                    entitySet, 
                    new EntityType("E", "N", DataSpace.CSpace),
                    new EdmFunction("F", "N", DataSpace.SSpace), 
                    new ModificationFunctionParameterBinding[0], 
                    null, 
                    null);

            modificationFunctionConfiguration.Configure(
                storageModificationFunctionMapping,
                ProviderRegistry.Sql2008_ProviderManifest);

            Assert.Equal("rows_affected", storageModificationFunctionMapping.RowsAffectedParameterName);
        }
 /// <summary>
 /// Initializes a new ModificationFunctionMapping instance.
 /// </summary>
 /// <param name="entitySet">The entity or association set.</param>
 /// <param name="entityType">The entity or association type.</param>
 /// <param name="function">The metadata of function to which we should bind.</param>
 /// <param name="parameterBindings">Bindings for function parameters.</param>
 /// <param name="rowsAffectedParameter">The output parameter producing number of rows affected.</param>
 /// <param name="resultBindings">Bindings for the results of function evaluation</param>
 public ModificationFunctionMapping(
     EntitySetBase entitySet,
     EntityTypeBase entityType,
     EdmFunction function,
     IEnumerable <ModificationFunctionParameterBinding> parameterBindings,
     FunctionParameter rowsAffectedParameter,
     IEnumerable <ModificationFunctionResultBinding> resultBindings)
 {
     Check.NotNull <EntitySetBase>(entitySet, nameof(entitySet));
     Check.NotNull <EdmFunction>(function, nameof(function));
     Check.NotNull <IEnumerable <ModificationFunctionParameterBinding> >(parameterBindings, nameof(parameterBindings));
     this._function = function;
     this._rowsAffectedParameter = rowsAffectedParameter;
     this._parameterBindings     = new ReadOnlyCollection <ModificationFunctionParameterBinding>((IList <ModificationFunctionParameterBinding>)parameterBindings.ToList <ModificationFunctionParameterBinding>());
     if (resultBindings != null)
     {
         List <ModificationFunctionResultBinding> list = resultBindings.ToList <ModificationFunctionResultBinding>();
         if (0 < list.Count)
         {
             this._resultBindings = new ReadOnlyCollection <ModificationFunctionResultBinding>((IList <ModificationFunctionResultBinding>)list);
         }
     }
     this._collocatedAssociationSetEnds = new ReadOnlyCollection <AssociationSetEnd>((IList <AssociationSetEnd>)ModificationFunctionMapping.GetReferencedAssociationSetEnds(entitySet as EntitySet, entityType as EntityType, parameterBindings).ToList <AssociationSetEnd>());
 }
        private void ConfigureSchema(ModificationFunctionMapping modificationStoredProcedureMapping)
        {
            DebugCheck.NotNull(modificationStoredProcedureMapping);

            if (!string.IsNullOrWhiteSpace(_schema))
            {
                modificationStoredProcedureMapping.Function.Schema = _schema;
            }
        }
        public void WriteFunctionMapping_should_write_association_end_bindings()
        {
            var fixture = new Fixture();

            var entityType = new EntityType("E", "N", DataSpace.CSpace);
            var entitySet = new EntitySet("ES", "S", null, null, entityType);
            new EntityContainer("EC", DataSpace.SSpace).AddEntitySetBase(entitySet);
            var associationSet = new AssociationSet("AS", new AssociationType("A", XmlConstants.ModelNamespace_3, false, DataSpace.CSpace));

            var associationEndMember1 = new AssociationEndMember("Source", new EntityType("E", "N", DataSpace.CSpace));
            associationSet.AddAssociationSetEnd(new AssociationSetEnd(entitySet, associationSet, associationEndMember1));

            var associationEndMember2 = new AssociationEndMember("Target", new EntityType("E", "N", DataSpace.CSpace));
            associationSet.AddAssociationSetEnd(new AssociationSetEnd(entitySet, associationSet, associationEndMember2));

            var storageModificationFunctionMapping
                = new ModificationFunctionMapping(
                    entitySet,
                    entityType,
                    new EdmFunction("F", "N", DataSpace.SSpace, new EdmFunctionPayload()),
                    new[]
                        {
                            new ModificationFunctionParameterBinding(
                                new FunctionParameter(
                                "P",
                                TypeUsage.Create(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32)),
                                ParameterMode.In),
                                new ModificationFunctionMemberPath(
                                new EdmMember[]
                                    {
                                        new EdmProperty("K"),
                                        associationEndMember1
                                    },
                                associationSet),
                                true)
                        },
                    null,
                    null);

            fixture.Writer.WriteFunctionMapping("InsertFunction", storageModificationFunctionMapping);

            Assert.Equal(
                @"<InsertFunction FunctionName=""N.F"">
  <AssociationEnd AssociationSet=""AS"" From=""Source"" To=""Target"">
    <ScalarProperty Name=""K"" ParameterName=""P"" Version=""Current"" />
  </AssociationEnd>
</InsertFunction>",
                fixture.ToString());
        }
        public void Can_retrieve_properties_and_set_read_only()
        {
            var associationType = new AssociationType("A", "N", false, DataSpace.CSpace);
            var associationSet = new AssociationSet("AS", associationType);

            associationSet.ChangeEntityContainerWithoutCollectionFixup(new EntityContainer("C", DataSpace.CSpace));

            var deleteModificationFunctionMapping
                = new ModificationFunctionMapping(
                    associationSet,
                    new EntityType("E", "N", DataSpace.CSpace),
                    new EdmFunction("F", "N", DataSpace.SSpace),
                    new[]
                        {
                            new ModificationFunctionParameterBinding(
                                new FunctionParameter(),
                                new ModificationFunctionMemberPath(
                                new EdmMember[]
                                    {
                                        new EdmProperty("M")
                                    },
                                null),
                                false)
                        },
                    null,
                    null);

            var insertModificationFunctionMapping
                = new ModificationFunctionMapping(
                    associationSet,
                    new EntityType("E", "N", DataSpace.CSpace),
                    new EdmFunction("F", "N", DataSpace.SSpace),
                    new[]
                        {
                            new ModificationFunctionParameterBinding(
                                new FunctionParameter(),
                                new ModificationFunctionMemberPath(
                                new EdmMember[]
                                    {
                                        new EdmProperty("M")
                                    },
                                null),
                                false)
                        },
                    null,
                    null);


            var associationSetModificationFunctionMapping
                = new AssociationSetModificationFunctionMapping(
                    associationSet,
                    deleteModificationFunctionMapping,
                    insertModificationFunctionMapping);

            Assert.Same(associationSetModificationFunctionMapping.AssociationSet, associationSet);
            Assert.Same(associationSetModificationFunctionMapping.DeleteFunctionMapping, deleteModificationFunctionMapping);
            Assert.Same(associationSetModificationFunctionMapping.InsertFunctionMapping, insertModificationFunctionMapping);

            Assert.False(associationSetModificationFunctionMapping.IsReadOnly);
            Assert.False(deleteModificationFunctionMapping.IsReadOnly);
            Assert.False(insertModificationFunctionMapping.IsReadOnly);

            associationSetModificationFunctionMapping.SetReadOnly();

            Assert.True(associationSetModificationFunctionMapping.IsReadOnly);
            Assert.True(deleteModificationFunctionMapping.IsReadOnly);
            Assert.True(insertModificationFunctionMapping.IsReadOnly);
        }
        public void Can_get_rows_affected_parameter_name()
        {
            var entityType = new EntityType("E", "N", DataSpace.CSpace);
            var entitySet = new EntitySet("ES", "S", null, null, entityType);
            var entityContainer = new EntityContainer("EC", DataSpace.SSpace);

            entityContainer.AddEntitySetBase(entitySet);

            var storageModificationFunctionMapping
                = new ModificationFunctionMapping(
                    entitySet,
                    entityType,
                    new EdmFunction("F", "N", DataSpace.SSpace, new EdmFunctionPayload()),
                    Enumerable.Empty<ModificationFunctionParameterBinding>(),
                    new FunctionParameter("rows_affected", new TypeUsage(), ParameterMode.Out),
                    null);

            Assert.Equal("rows_affected", storageModificationFunctionMapping.RowsAffectedParameterName);
        }
        private void ConfigureParameters(ModificationFunctionMapping modificationStoredProcedureMapping)
        {
            foreach (var keyValue in _parameterNames)
            {
                var propertyPath = keyValue.Key.PropertyPath;
                var parameterName = keyValue.Value.Item1;
                var originalValueParameterName = keyValue.Value.Item2;

                var parameterBindings
                    = modificationStoredProcedureMapping
                        .ParameterBindings
                        .Where(
                            pb => // First, try and match scalar/complex/many-to-many binding 
                            (((pb.MemberPath.AssociationSetEnd == null)
                              || pb.MemberPath.AssociationSetEnd.ParentAssociationSet.ElementType.IsManyToMany())
                             && propertyPath.Equals(
                                 new PropertyPath(
                                    pb.MemberPath.Members.OfType<EdmProperty>().Select(m => m.GetClrPropertyInfo()))))
                            ||
                            // Otherwise, try and match IA FK bindings 
                            ((propertyPath.Count == 2)
                             && (pb.MemberPath.AssociationSetEnd != null)
                             && pb.MemberPath.Members.First().GetClrPropertyInfo().IsSameAs(propertyPath.Last())
                             && pb.MemberPath.AssociationSetEnd.ParentAssociationSet.AssociationSetEnds
                                    .Select(ae => ae.CorrespondingAssociationEndMember.GetClrPropertyInfo())
                                    .Where(pi => pi != null)
                                    .Any(pi => pi.IsSameAs(propertyPath.First()))))
                        .ToList();

                if (parameterBindings.Count == 1)
                {
                    var parameterBinding = parameterBindings.Single();

                    if (!string.IsNullOrWhiteSpace(originalValueParameterName))
                    {
                        if (parameterBinding.IsCurrent)
                        {
                            throw Error.ModificationFunctionParameterNotFoundOriginal(
                                propertyPath,
                                modificationStoredProcedureMapping.Function.FunctionName);
                        }
                    }

                    parameterBinding.Parameter.Name = parameterName;

                    _configuredParameters.Add(parameterBinding.Parameter);
                }
                else if (parameterBindings.Count == 2)
                {
                    var parameterBinding
                        = ((parameterBindings
                                .Select(pb => pb.IsCurrent)
                                .Distinct()
                                .Count() == 1) // same value for both
                           && parameterBindings
                                  .All(pb => pb.MemberPath.AssociationSetEnd != null))
                              ? !keyValue.Key.IsRightKey
                                    ? parameterBindings.First()
                                    : parameterBindings.Last()
                              : parameterBindings.Single(pb => pb.IsCurrent);

                    parameterBinding.Parameter.Name = parameterName;

                    _configuredParameters.Add(parameterBinding.Parameter);

                    if (!string.IsNullOrWhiteSpace(originalValueParameterName))
                    {
                        parameterBinding = parameterBindings.Single(pb => !pb.IsCurrent);

                        parameterBinding.Parameter.Name = originalValueParameterName;

                        _configuredParameters.Add(parameterBinding.Parameter);
                    }
                }
                else
                {
                    throw Error.ModificationFunctionParameterNotFound(
                        propertyPath,
                        modificationStoredProcedureMapping.Function.FunctionName);
                }
            }

            var unconfiguredParameters
                = modificationStoredProcedureMapping
                    .Function
                    .Parameters
                    .Except(_configuredParameters);

            foreach (var parameter in unconfiguredParameters)
            {
                parameter.Name
                    = modificationStoredProcedureMapping
                        .Function
                        .Parameters
                        .Except(new[] { parameter })
                        .UniquifyName(parameter.Name);
            }
        }
        private ModificationFunctionMapping GenerateFunctionMapping(
            ModificationOperator modificationOperator,
            EntitySetBase entitySetBase,
            EntityTypeBase entityTypeBase,
            DbDatabaseMapping databaseMapping,
            IEnumerable<EdmProperty> parameterProperties,
            IEnumerable<Tuple<ModificationFunctionMemberPath, EdmProperty>> iaFkProperties,
            IList<ColumnMappingBuilder> columnMappings,
            IEnumerable<EdmProperty> resultProperties = null,
            string functionNamePrefix = null)
        {
            DebugCheck.NotNull(entitySetBase);
            DebugCheck.NotNull(entityTypeBase);
            DebugCheck.NotNull(databaseMapping);
            DebugCheck.NotNull(parameterProperties);
            DebugCheck.NotNull(iaFkProperties);
            DebugCheck.NotNull(columnMappings);

            var useOriginalValues = modificationOperator == ModificationOperator.Delete;

            var parameterMappingGenerator
                = new FunctionParameterMappingGenerator(_providerManifest);

            var parameterBindings
                = parameterMappingGenerator
                    .Generate(
                        modificationOperator == ModificationOperator.Insert
                            && IsTableSplitDependent(entityTypeBase, databaseMapping)
                                ? ModificationOperator.Update 
                                : modificationOperator,
                        parameterProperties,
                        columnMappings,
                        new List<EdmProperty>(),
                        useOriginalValues)
                    .Concat(
                        parameterMappingGenerator
                            .Generate(iaFkProperties, useOriginalValues))
                    .ToList();

            var parameters
                = parameterBindings.Select(b => b.Parameter).ToList();

            UniquifyParameterNames(parameters);

            var functionPayload
                = new EdmFunctionPayload
                      {
                          ReturnParameters = new FunctionParameter[0],
                          Parameters = parameters.ToArray(),
                          IsComposable = false
                      };

            var function
                = databaseMapping.Database
                    .AddFunction(
                        (functionNamePrefix ?? entityTypeBase.Name) + "_" + modificationOperator.ToString(),
                        functionPayload);

            var functionMapping
                = new ModificationFunctionMapping(
                    entitySetBase,
                    entityTypeBase,
                    function,
                    parameterBindings,
                    null,
                    resultProperties != null
                        ? resultProperties.Select(
                            p => new ModificationFunctionResultBinding(
                                     columnMappings.First(cm => cm.PropertyPath.SequenceEqual(new[] { p })).ColumnProperty.Name,
                                     p))
                        : null);

            return functionMapping;
        }
        public void GetComplexParameterBindings_should_return_all_complex_parameter_bindings_for_type()
        {
            var databaseMapping
                = new DbDatabaseMapping()
                    .Initialize(
                        new EdmModel(DataSpace.CSpace),
                        new EdmModel(DataSpace.SSpace));

            var entityType = new EntityType("E", "N", DataSpace.CSpace);
            var entitySet = databaseMapping.Model.AddEntitySet("ES", entityType);
            var entitySetMapping = databaseMapping.AddEntitySetMapping(entitySet);

            var complexType1 = new ComplexType();
            complexType1.GetMetadataProperties().SetClrType(typeof(string));

            var complexType2 = new ComplexType();
            complexType2.GetMetadataProperties().SetClrType(typeof(object));

            var storageModificationFunctionMapping
                = new ModificationFunctionMapping(
                    entitySet,
                    entityType,
                    new EdmFunction("F", "N", DataSpace.SSpace),
                    new[]
                        {
                            new ModificationFunctionParameterBinding(
                                new FunctionParameter(),
                                new ModificationFunctionMemberPath(
                                new EdmMember[]
                                    {
                                        EdmProperty.CreateComplex("C1", complexType1),
                                        EdmProperty.CreateComplex("C2", complexType2),
                                        new EdmProperty("M")
                                    },
                                null),
                                true
                                )
                        },
                    null,
                    null);

            entitySetMapping.AddModificationFunctionMapping(
                new EntityTypeModificationFunctionMapping(
                    entityType,
                    storageModificationFunctionMapping,
                    storageModificationFunctionMapping,
                    storageModificationFunctionMapping));

            Assert.Equal(3, databaseMapping.GetComplexParameterBindings(typeof(string)).Count());
            Assert.Equal(3, databaseMapping.GetComplexParameterBindings(typeof(object)).Count());
        }