public void Can_generate_scalar_and_complex_properties_when_update()
        {
            var functionParameterMappingGenerator
                = new FunctionParameterMappingGenerator(ProviderRegistry.Sql2008_ProviderManifest);

            var property0 = new EdmProperty("P0");
            var property1 = new EdmProperty("P1");
            var property2 = new EdmProperty("P2");

            property2.SetStoreGeneratedPattern(StoreGeneratedPattern.Computed);
            property2.ConcurrencyMode = ConcurrencyMode.Fixed;

            var complexType = new ComplexType("CT", "N", DataSpace.CSpace);

            complexType.AddMember(property1);

            var complexProperty = EdmProperty.CreateComplex("C", complexType);

            var parameterBindings
                = functionParameterMappingGenerator
                    .Generate(
                        ModificationOperator.Update,
                        new[] { property0, complexProperty, property2 },
                        new[]
                            {
                                new ColumnMappingBuilder(new EdmProperty("C0"), new[] { property0 }),
                                new ColumnMappingBuilder(new EdmProperty("C_P1"), new[] { complexProperty, property1 }),
                                new ColumnMappingBuilder(new EdmProperty("C2"), new[] { property2 })
                            },
                        new List<EdmProperty>(),
                        useOriginalValues: true)
                    .ToList();

            Assert.Equal(3, parameterBindings.Count());

            var parameterBinding = parameterBindings.First();

            Assert.Equal("C0", parameterBinding.Parameter.Name);
            Assert.Same(property0, parameterBinding.MemberPath.Members.Single());
            Assert.Equal("String", parameterBinding.Parameter.TypeName);
            Assert.Equal(ParameterMode.In, parameterBinding.Parameter.Mode);
            Assert.False(parameterBinding.IsCurrent);

            parameterBinding = parameterBindings.ElementAt(1);

            Assert.Equal("C_P1", parameterBinding.Parameter.Name);
            Assert.Same(complexProperty, parameterBinding.MemberPath.Members.First());
            Assert.Same(property1, parameterBinding.MemberPath.Members.Last());
            Assert.Equal("String", parameterBinding.Parameter.TypeName);
            Assert.Equal(ParameterMode.In, parameterBinding.Parameter.Mode);
            Assert.False(parameterBinding.IsCurrent);

            parameterBinding = parameterBindings.Last();

            Assert.Equal("C2_Original", parameterBinding.Parameter.Name);
            Assert.Same(property2, parameterBinding.MemberPath.Members.Single());
            Assert.Equal("String", parameterBinding.Parameter.TypeName);
            Assert.Equal(ParameterMode.In, parameterBinding.Parameter.Mode);
            Assert.False(parameterBinding.IsCurrent);
        }
예제 #2
0
        public void Can_generate_scalar_and_complex_properties_when_update()
        {
            var functionParameterMappingGenerator
                = new FunctionParameterMappingGenerator(ProviderRegistry.Sql2008_ProviderManifest);

            var property0 = new EdmProperty("P0");
            var property1 = new EdmProperty("P1");
            var property2 = new EdmProperty("P2");

            property2.SetStoreGeneratedPattern(StoreGeneratedPattern.Computed);
            property2.ConcurrencyMode = ConcurrencyMode.Fixed;

            var complexType = new ComplexType("CT", "N", DataSpace.CSpace);

            complexType.AddMember(property1);

            var complexProperty = EdmProperty.Complex("C", complexType);

            var parameterBindings
                = functionParameterMappingGenerator
                  .Generate(
                      ModificationOperator.Update,
                      new[] { property0, complexProperty, property2 },
                      new[]
            {
                new ColumnMappingBuilder(new EdmProperty("C0"), new[] { property0 }),
                new ColumnMappingBuilder(new EdmProperty("C_P1"), new[] { complexProperty, property1 }),
                new ColumnMappingBuilder(new EdmProperty("C2"), new[] { property2 })
            },
                      new List <EdmProperty>(),
                      useOriginalValues: true)
                  .ToList();

            Assert.Equal(3, parameterBindings.Count());

            var parameterBinding = parameterBindings.First();

            Assert.Equal("C0", parameterBinding.Parameter.Name);
            Assert.Same(property0, parameterBinding.MemberPath.Members.Single());
            Assert.Equal("String", parameterBinding.Parameter.TypeName);
            Assert.Equal(ParameterMode.In, parameterBinding.Parameter.Mode);
            Assert.False(parameterBinding.IsCurrent);

            parameterBinding = parameterBindings.ElementAt(1);

            Assert.Equal("C_P1", parameterBinding.Parameter.Name);
            Assert.Same(complexProperty, parameterBinding.MemberPath.Members.First());
            Assert.Same(property1, parameterBinding.MemberPath.Members.Last());
            Assert.Equal("String", parameterBinding.Parameter.TypeName);
            Assert.Equal(ParameterMode.In, parameterBinding.Parameter.Mode);
            Assert.False(parameterBinding.IsCurrent);

            parameterBinding = parameterBindings.Last();

            Assert.Equal("C2_Original", parameterBinding.Parameter.Name);
            Assert.Same(property2, parameterBinding.MemberPath.Members.Single());
            Assert.Equal("String", parameterBinding.Parameter.TypeName);
            Assert.Equal(ParameterMode.In, parameterBinding.Parameter.Mode);
            Assert.False(parameterBinding.IsCurrent);
        }
예제 #3
0
        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)
        {
            bool useOriginalValues = modificationOperator == ModificationOperator.Delete;
            FunctionParameterMappingGenerator           mappingGenerator = new FunctionParameterMappingGenerator(this._providerManifest);
            List <ModificationFunctionParameterBinding> list1            = mappingGenerator.Generate(modificationOperator != ModificationOperator.Insert || !ModificationFunctionMappingGenerator.IsTableSplitDependent(entityTypeBase, databaseMapping) ? modificationOperator : ModificationOperator.Update, parameterProperties, columnMappings, (IList <EdmProperty>) new List <EdmProperty>(), useOriginalValues).Concat <ModificationFunctionParameterBinding>(mappingGenerator.Generate(iaFkProperties, useOriginalValues)).ToList <ModificationFunctionParameterBinding>();
            List <FunctionParameter> list2 = list1.Select <ModificationFunctionParameterBinding, FunctionParameter>((Func <ModificationFunctionParameterBinding, FunctionParameter>)(b => b.Parameter)).ToList <FunctionParameter>();

            ModificationFunctionMappingGenerator.UniquifyParameterNames((IList <FunctionParameter>)list2);
            EdmFunctionPayload functionPayload = new EdmFunctionPayload()
            {
                ReturnParameters = (IList <FunctionParameter>) new FunctionParameter[0],
                Parameters       = (IList <FunctionParameter>)list2.ToArray(),
                IsComposable     = new bool?(false)
            };
            EdmFunction function = databaseMapping.Database.AddFunction((functionNamePrefix ?? entityTypeBase.Name) + "_" + modificationOperator.ToString(), functionPayload);

            return(new ModificationFunctionMapping(entitySetBase, entityTypeBase, function, (IEnumerable <ModificationFunctionParameterBinding>)list1, (FunctionParameter)null, resultProperties != null ? resultProperties.Select <EdmProperty, ModificationFunctionResultBinding>((Func <EdmProperty, ModificationFunctionResultBinding>)(p => new ModificationFunctionResultBinding(columnMappings.First <ColumnMappingBuilder>((Func <ColumnMappingBuilder, bool>)(cm => cm.PropertyPath.SequenceEqual <EdmProperty>((IEnumerable <EdmProperty>) new EdmProperty[1]
            {
                p
            }))).ColumnProperty.Name, p))) : (IEnumerable <ModificationFunctionResultBinding>)null));
        }
예제 #4
0
        public void Generate_should_throw_when_circular_complex_property()
        {
            var functionParameterMappingGenerator
                = new FunctionParameterMappingGenerator(ProviderRegistry.Sql2008_ProviderManifest);

            var complexType = new ComplexType("CT", "N", DataSpace.CSpace);

            complexType.AddMember(EdmProperty.Complex("C1", complexType));

            Assert.Equal(
                Strings.CircularComplexTypeHierarchy,
                Assert.Throws <InvalidOperationException>(
                    () => functionParameterMappingGenerator
                    .Generate(
                        ModificationOperator.Insert,
                        new[] { EdmProperty.Complex("C0", complexType) },
                        new ColumnMappingBuilder[0],
                        new List <EdmProperty>())
                    .ToList()).Message);
        }
예제 #5
0
        public void Can_generate_ia_fk_parameters()
        {
            var functionParameterMappingGenerator
                = new FunctionParameterMappingGenerator(ProviderRegistry.Sql2008_ProviderManifest);

            var associationType
                = new AssociationType("A", XmlConstants.ModelNamespace_3, false, DataSpace.CSpace)
                {
                SourceEnd = new AssociationEndMember("S", new EntityType("E", "N", DataSpace.CSpace)),
                TargetEnd = new AssociationEndMember("T", new EntityType("E", "N", DataSpace.CSpace))
                };

            var associationSet
                = new AssociationSet("AS", associationType)
                {
                SourceSet = new EntitySet(),
                TargetSet = new EntitySet()
                };

            var memberPath
                = new StorageModificationFunctionMemberPath(
                      new EdmMember[] { new EdmProperty("P"), associationType.TargetEnd },
                      associationSet);

            var parameterBindings
                = functionParameterMappingGenerator
                  .Generate(
                      new[] { Tuple.Create(memberPath, new EdmProperty("param")) },
                      useOriginalValues: true)
                  .ToList();

            var parameterBinding = parameterBindings.Single();

            Assert.Equal("param", parameterBinding.Parameter.Name);
            Assert.Same(memberPath, parameterBinding.MemberPath);
            Assert.Equal("String", parameterBinding.Parameter.TypeName);
            Assert.Equal(ParameterMode.In, parameterBinding.Parameter.Mode);
            Assert.False(parameterBinding.IsCurrent);
        }
        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,
                      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);
        }
        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;
        }
        private StorageModificationFunctionMapping GenerateFunctionMapping(
            ModificationOperator modificationOperator,
            EntitySetBase entitySetBase,
            EntityTypeBase entityTypeBase,
            DbDatabaseMapping databaseMapping,
            IEnumerable <EdmProperty> parameterProperties,
            IEnumerable <Tuple <StorageModificationFunctionMemberPath, EdmProperty> > iaFkProperties,
            IList <ColumnMappingBuilder> columnMappings,
            IEnumerable <EdmProperty> resultProperties = 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,
                      parameterProperties,
                      columnMappings,
                      new List <EdmProperty>(),
                      useOriginalValues)
                  .Concat(
                      parameterMappingGenerator
                      .Generate(iaFkProperties, useOriginalValues))
                  .ToList();

            FunctionParameter rowsAffectedParameter = null;

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

            if (parameterBindings
                .Any(
                    pb => !pb.IsCurrent &&
                    pb.MemberPath.AssociationSetEnd == null &&
                    ((EdmProperty)pb.MemberPath.Members.Last()).ConcurrencyMode == ConcurrencyMode.Fixed))
            {
                rowsAffectedParameter
                    = new FunctionParameter(
                          "RowsAffected",
                          _providerManifest.GetStoreType(
                              TypeUsage.CreateDefaultTypeUsage(
                                  PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32))),
                          ParameterMode.Out);

                parameters.Add(rowsAffectedParameter);
            }

            UniquifyParameterNames(parameters);

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

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

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

            return(functionMapping);
        }
        public void Generate_should_throw_when_circular_complex_property()
        {
            var functionParameterMappingGenerator
                = new FunctionParameterMappingGenerator(ProviderRegistry.Sql2008_ProviderManifest);

            var complexType = new ComplexType("CT", "N", DataSpace.CSpace);
            complexType.AddMember(EdmProperty.CreateComplex("C1", complexType));

            Assert.Equal(
                Strings.CircularComplexTypeHierarchy,
                Assert.Throws<InvalidOperationException>(
                    () => functionParameterMappingGenerator
                              .Generate(
                                  ModificationOperator.Insert,
                                  new[] { EdmProperty.CreateComplex("C0", complexType) },
                                  new ColumnMappingBuilder[0],
                                  new List<EdmProperty>())
                              .ToList()).Message);
        }
        public void Can_generate_ia_fk_parameters()
        {
            var functionParameterMappingGenerator
                = new FunctionParameterMappingGenerator(ProviderRegistry.Sql2008_ProviderManifest);

            var associationType
                = new AssociationType("A", XmlConstants.ModelNamespace_3, false, DataSpace.CSpace)
                      {
                          SourceEnd = new AssociationEndMember("S", new EntityType("E", "N", DataSpace.CSpace)),
                          TargetEnd = new AssociationEndMember("T", new EntityType("E", "N", DataSpace.CSpace))
                      };

            var associationSet
                = new AssociationSet("AS", associationType)
                      {
                          SourceSet = new EntitySet(),
                          TargetSet = new EntitySet()
                      };

            var memberPath
                = new ModificationFunctionMemberPath(
                    new EdmMember[] { new EdmProperty("P"), associationType.TargetEnd },
                    associationSet);

            var parameterBindings
                = functionParameterMappingGenerator
                    .Generate(
                        new[] { Tuple.Create(memberPath, new EdmProperty("param")) },
                        useOriginalValues: true)
                    .ToList();

            var parameterBinding = parameterBindings.Single();

            Assert.Equal("param", parameterBinding.Parameter.Name);
            Assert.Same(memberPath, parameterBinding.MemberPath);
            Assert.Equal("String", parameterBinding.Parameter.TypeName);
            Assert.Equal(ParameterMode.In, parameterBinding.Parameter.Mode);
            Assert.False(parameterBinding.IsCurrent);
        }
        private StorageModificationFunctionMapping GenerateFunctionMapping(
            ModificationOperator modificationOperator,
            EntitySetBase entitySetBase,
            EntityTypeBase entityTypeBase,
            DbDatabaseMapping databaseMapping,
            IEnumerable<EdmProperty> parameterProperties,
            IEnumerable<Tuple<StorageModificationFunctionMemberPath, EdmProperty>> iaFkProperties,
            IList<ColumnMappingBuilder> columnMappings,
            IEnumerable<EdmProperty> resultProperties = 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,
                        parameterProperties,
                        columnMappings,
                        new List<EdmProperty>(),
                        useOriginalValues)
                    .Concat(
                        parameterMappingGenerator
                            .Generate(iaFkProperties, useOriginalValues))
                    .ToList();

            FunctionParameter rowsAffectedParameter = null;

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

            if (parameterBindings
                .Any(
                    pb => !pb.IsCurrent
                          && pb.MemberPath.AssociationSetEnd == null
                          && ((EdmProperty)pb.MemberPath.Members.Last()).ConcurrencyMode == ConcurrencyMode.Fixed))
            {
                rowsAffectedParameter
                    = new FunctionParameter(
                        "RowsAffected",
                        _providerManifest.GetStoreType(
                            TypeUsage.CreateDefaultTypeUsage(
                                PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32))),
                        ParameterMode.Out);

                parameters.Add(rowsAffectedParameter);
            }

            UniquifyParameterNames(parameters);

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

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

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

            return functionMapping;
        }