Example #1
0
        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 StorageEntitySetMapping(
                    entitySet,
                    new StorageEntityContainerMapping(container));

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

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

            entitySetMapping.AddModificationFunctionMapping(entityFunctionMappings);

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

            entitySetMapping.ClearModificationFunctionMappings();

            Assert.Equal(0, entitySetMapping.ModificationFunctionMappings.Count());
        }
        public void PrimaryParameterBindings_should_omit_original_value_parameters_when_update()
        {
            var entitySet = new EntitySet();
            entitySet.ChangeEntityContainerWithoutCollectionFixup(new EntityContainer("C", DataSpace.CSpace));

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

            var storageEntityTypeModificationFunctionMapping
                = new StorageEntityTypeModificationFunctionMapping(
                    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 StorageEntitySetMapping(
                    entitySet,
                    new StorageEntityContainerMapping(container));

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

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

            entitySetMapping.AddModificationFunctionMapping(entityFunctionMappings);

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

            entitySetMapping.ClearModificationFunctionMappings();

            Assert.Equal(0, entitySetMapping.ModificationFunctionMappings.Count());
        }
        public void PrimaryParameterBindings_should_omit_original_value_parameters_when_update()
        {
            var entitySet = new EntitySet();

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

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

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

            Assert.Equal(2, storageEntityTypeModificationFunctionMapping.PrimaryParameterBindings.Count());
        }
 internal void AssertModificationFunctionMappingInvariants(StorageEntityTypeModificationFunctionMapping modificationFunctionMapping)
 {
     DebugCheck.NotNull(modificationFunctionMapping);
     Debug.Assert(
         modificationFunctionMapping.EntityType.Equals(Set.ElementType) ||
         Helper.IsSubtypeOf(modificationFunctionMapping.EntityType, Set.ElementType),
         "attempting to add a modification function mapping with the wrong entity type");
     foreach (var existingMapping in m_modificationFunctionMappings)
     {
         Debug.Assert(
             !existingMapping.EntityType.Equals(modificationFunctionMapping.EntityType),
             "modification function mapping already exists for this type");
     }
 }
        public virtual void Configure(StorageEntityTypeModificationFunctionMapping modificationFunctionMapping)
        {
            DebugCheck.NotNull(modificationFunctionMapping);

            if (_insertModificationFunctionConfiguration != null)
            {
                _insertModificationFunctionConfiguration
                    .Configure(modificationFunctionMapping.InsertFunctionMapping);
            }

            if (_updateModificationFunctionConfiguration != null)
            {
                _updateModificationFunctionConfiguration
                    .Configure(modificationFunctionMapping.UpdateFunctionMapping);
            }

            if (_deleteModificationFunctionConfiguration != null)
            {
                _deleteModificationFunctionConfiguration
                    .Configure(modificationFunctionMapping.DeleteFunctionMapping);
            }
        }
Example #7
0
        public void Can_get_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 StorageEntitySetMapping(
                    entitySet,
                    new StorageEntityContainerMapping(container));

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

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

            entitySetMapping.AddModificationFunctionMapping(entityFunctionMappings);

            Assert.Same(entityFunctionMappings, entitySetMapping.ModificationFunctionMappings.Single());
        }
        /// <summary>
        ///     Requires:
        ///     - Function mapping refers to a sub-type of this entity set's element type
        ///     - Function mappings for types are not redundantly specified
        ///     Adds a new function mapping for this class.
        /// </summary>
        /// <param name="modificationFunctionMapping"> Function mapping to add. May not be null. </param>
        internal void AddModificationFunctionMapping(StorageEntityTypeModificationFunctionMapping modificationFunctionMapping)
        {
            AssertModificationFunctionMappingInvariants(modificationFunctionMapping);

            m_modificationFunctionMappings.Add(modificationFunctionMapping);

            // check if any association sets are indirectly mapped within this function mapping
            // through association navigation bindings
            if (null != modificationFunctionMapping.DeleteFunctionMapping)
            {
                m_implicitlyMappedAssociationSetEnds.AddRange(
                    modificationFunctionMapping.DeleteFunctionMapping.CollocatedAssociationSetEnds);
            }
            if (null != modificationFunctionMapping.InsertFunctionMapping)
            {
                m_implicitlyMappedAssociationSetEnds.AddRange(
                    modificationFunctionMapping.InsertFunctionMapping.CollocatedAssociationSetEnds);
            }
            if (null != modificationFunctionMapping.UpdateFunctionMapping)
            {
                m_implicitlyMappedAssociationSetEnds.AddRange(
                    modificationFunctionMapping.UpdateFunctionMapping.CollocatedAssociationSetEnds);
            }
        }
 internal void AssertModificationFunctionMappingInvariants(StorageEntityTypeModificationFunctionMapping modificationFunctionMapping)
 {
     Debug.Assert(null != modificationFunctionMapping, "modification function mapping must not be null");
     Debug.Assert(
         modificationFunctionMapping.EntityType.Equals(Set.ElementType) ||
         Helper.IsSubtypeOf(modificationFunctionMapping.EntityType, Set.ElementType),
         "attempting to add a modification function mapping with the wrong entity type");
     foreach (var existingMapping in m_modificationFunctionMappings)
     {
         Debug.Assert(
             !existingMapping.EntityType.Equals(modificationFunctionMapping.EntityType),
             "modification function mapping already exists for this type");
     }
 }
        /// <summary>
        ///     Requires:
        ///     - Function mapping refers to a sub-type of this entity set's element type
        ///     - Function mappings for types are not redundantly specified
        ///     Adds a new function mapping for this class.
        /// </summary>
        /// <param name="modificationFunctionMapping"> Function mapping to add. May not be null. </param>
        internal void AddModificationFunctionMapping(StorageEntityTypeModificationFunctionMapping modificationFunctionMapping)
        {
            AssertModificationFunctionMappingInvariants(modificationFunctionMapping);

            m_modificationFunctionMappings.Add(modificationFunctionMapping);

            // check if any association sets are indirectly mapped within this function mapping
            // through association navigation bindings
            if (null != modificationFunctionMapping.DeleteFunctionMapping)
            {
                m_implicitlyMappedAssociationSetEnds.AddRange(
                    modificationFunctionMapping.DeleteFunctionMapping.CollocatedAssociationSetEnds);
            }
            if (null != modificationFunctionMapping.InsertFunctionMapping)
            {
                m_implicitlyMappedAssociationSetEnds.AddRange(
                    modificationFunctionMapping.InsertFunctionMapping.CollocatedAssociationSetEnds);
            }
            if (null != modificationFunctionMapping.UpdateFunctionMapping)
            {
                m_implicitlyMappedAssociationSetEnds.AddRange(
                    modificationFunctionMapping.UpdateFunctionMapping.CollocatedAssociationSetEnds);
            }
        }
        private void WriteModificationFunctionMapping(StorageEntityTypeModificationFunctionMapping modificationFunctionMapping)
        {
            DebugCheck.NotNull(modificationFunctionMapping);

            _xmlWriter.WriteStartElement(StorageMslConstructs.ModificationFunctionMappingElement);

            WriteFunctionMapping(StorageMslConstructs.InsertFunctionElement, modificationFunctionMapping.InsertFunctionMapping);
            WriteFunctionMapping(StorageMslConstructs.UpdateFunctionElement, modificationFunctionMapping.UpdateFunctionMapping);
            WriteFunctionMapping(StorageMslConstructs.DeleteFunctionElement, modificationFunctionMapping.DeleteFunctionMapping);

            _xmlWriter.WriteEndElement();
        }
        public void Can_get_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 StorageEntitySetMapping(
                    entitySet,
                    new StorageEntityContainerMapping(container));

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

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

            entitySetMapping.AddModificationFunctionMapping(entityFunctionMappings);

            Assert.Same(entityFunctionMappings, entitySetMapping.ModificationFunctionMappings.Single());
        }
        /// <summary>
        ///     Finds interesting members for modification functions mapped to stored procedures and adds them to the <paramref
        ///      name="interestingMembers" />.
        /// </summary>
        /// <param name="functionMappings"> Modification function mapping. Must not be null. </param>
        /// <param name="interestingMembersKind"> Update scenario the members will be used in (in general - partial update vs. full update). </param>
        /// <param name="interestingMembers"> </param>
        private static void FindInterestingFunctionMappingMembers(
            StorageEntityTypeModificationFunctionMapping functionMappings, InterestingMembersKind interestingMembersKind,
            ref List<EdmMember> interestingMembers)
        {
            Debug.Assert(
                functionMappings != null && functionMappings.UpdateFunctionMapping != null,
                "Expected function mapping fragment with non-null update function mapping");
            Debug.Assert(interestingMembers != null, "interestingMembers != null");

            // for partial update scenarios (e.g. EntityDataSourceControl) all members are interesting otherwise the data may be corrupt. 
            // See bugs #272992 and #124460 in DevDiv database for more details. For full update scenarios and the obsolete 
            // MetadataWorkspace.GetRequiredOriginalValueMembers() metod we return only members with Version set to "Original".
            if (interestingMembersKind == InterestingMembersKind.PartialUpdate)
            {
                // (5) Members included in Update ModificationFunction
                interestingMembers.AddRange(
                    functionMappings.UpdateFunctionMapping.ParameterBindings.Select(p => p.MemberPath.Members.Last()));
            }
            else
            {
                //(4) Members in update ModificationFunction with Version="Original" are "interesting"
                // This also works when you have complex-types (4.1)

                Debug.Assert(
                    interestingMembersKind == InterestingMembersKind.FullUpdate
                    || interestingMembersKind == InterestingMembersKind.RequiredOriginalValueMembers,
                    "Unexpected kind of interesting members - if you changed the InterestingMembersKind enum type update this code accordingly");

                foreach (var parameterBinding in functionMappings.UpdateFunctionMapping.ParameterBindings.Where(p => !p.IsCurrent))
                {
                    //Last is the root element (with respect to the Entity)
                    //For example,  Entity1={
                    //                  S1, 
                    //                  C1{S2, 
                    //                     C2{ S3, S4 } 
                    //                     }, 
                    //                  S5}
                    // if S4 matches (i.e. C1.C2.S4), then it returns C1
                    //because internally the list is [S4][C2][C1]
                    interestingMembers.Add(parameterBinding.MemberPath.Members.Last());
                }
            }
        }
        private IEnumerable<CreateProcedureOperation> BuildCreateProcedureOperations(
            StorageEntityTypeModificationFunctionMapping modificationFunctionMapping,
            ModificationCommandTreeGenerator modificationCommandTreeGenerator,
            MigrationSqlGenerator migrationSqlGenerator)
        {
            DebugCheck.NotNull(modificationFunctionMapping);

            var insertCommandTrees = new DbInsertCommandTree[0];
            var updateCommandTrees = new DbUpdateCommandTree[0];
            var deleteCommandTrees = new DbDeleteCommandTree[0];

            if (modificationCommandTreeGenerator != null)
            {
                var dynamicToFunctionModificationCommandConverter
                    = new DynamicToFunctionModificationCommandConverter(
                        modificationFunctionMapping,
                        _target.StorageEntityContainerMapping);

                insertCommandTrees
                    = dynamicToFunctionModificationCommandConverter
                        .Convert(
                            modificationCommandTreeGenerator
                                .GenerateInsert(modificationFunctionMapping.EntityType.Identity))
                        .ToArray();

                updateCommandTrees
                    = dynamicToFunctionModificationCommandConverter
                        .Convert(
                            modificationCommandTreeGenerator
                                .GenerateUpdate(modificationFunctionMapping.EntityType.Identity))
                        .ToArray();

                deleteCommandTrees
                    = dynamicToFunctionModificationCommandConverter
                        .Convert(
                            modificationCommandTreeGenerator
                                .GenerateDelete(modificationFunctionMapping.EntityType.Identity))
                        .ToArray();
            }

            string insertBodySql = null, updateBodySql = null, deleteBodySql = null;

            if (migrationSqlGenerator != null)
            {
                var providerManifestToken
                    = _target.ProviderInfo.ProviderManifestToken;

                insertBodySql
                    = migrationSqlGenerator
                        .GenerateProcedureBody(insertCommandTrees, null, providerManifestToken);

                updateBodySql
                    = migrationSqlGenerator.GenerateProcedureBody(
                        updateCommandTrees,
                        modificationFunctionMapping.UpdateFunctionMapping.RowsAffectedParameterName,
                        providerManifestToken);

                deleteBodySql
                    = migrationSqlGenerator.GenerateProcedureBody(
                        deleteCommandTrees,
                        modificationFunctionMapping.DeleteFunctionMapping.RowsAffectedParameterName,
                        providerManifestToken);
            }

            yield return BuildCreateProcedureOperation(
                modificationFunctionMapping.InsertFunctionMapping.Function,
                insertBodySql);

            yield return BuildCreateProcedureOperation(
                modificationFunctionMapping.UpdateFunctionMapping.Function,
                updateBodySql);

            yield return BuildCreateProcedureOperation(
                modificationFunctionMapping.DeleteFunctionMapping.Function,
                deleteBodySql);
        }
        public void Generate(EntityType entityType, DbDatabaseMapping databaseMapping)
        {
            DebugCheck.NotNull(entityType);
            DebugCheck.NotNull(databaseMapping);

            if (entityType.Abstract)
            {
                return;
            }

            var entitySet = databaseMapping.Model.GetEntitySet(entityType);

            Debug.Assert(entitySet != null);

            var entitySetMapping = databaseMapping.GetEntitySetMapping(entitySet);

            Debug.Assert(entitySetMapping != null);

            var columnMappings = GetColumnMappings(entityType, entitySetMapping).ToList();
            var iaFkProperties = GetIndependentFkColumns(entityType, databaseMapping).ToList();

            var insertFunctionMapping
                = GenerateFunctionMapping(
                    ModificationOperator.Insert,
                    entitySetMapping.EntitySet,
                    entityType,
                    databaseMapping,
                    entityType.Properties,
                    iaFkProperties,
                    columnMappings,
                    entityType
                        .Properties
                        .Where(p => p.HasStoreGeneratedPattern()));

            var updateFunctionMapping
                = GenerateFunctionMapping(
                    ModificationOperator.Update,
                    entitySetMapping.EntitySet,
                    entityType,
                    databaseMapping,
                    entityType.Properties,
                    iaFkProperties,
                    columnMappings,
                    entityType
                        .Properties
                        .Where(p => p.GetStoreGeneratedPattern() == StoreGeneratedPattern.Computed));

            var deleteFunctionMapping
                = GenerateFunctionMapping(
                    ModificationOperator.Delete,
                    entitySetMapping.EntitySet,
                    entityType,
                    databaseMapping,
                    entityType.Properties,
                    iaFkProperties,
                    columnMappings);

            var modificationFunctionMapping
                = new StorageEntityTypeModificationFunctionMapping(
                    entityType,
                    deleteFunctionMapping,
                    insertFunctionMapping,
                    updateFunctionMapping);

            entitySetMapping.AddModificationFunctionMapping(modificationFunctionMapping);
        }