Exemple #1
0
        private void BuildSchema(DataUpdateContext context, UpdateStatement statement, TableIdentifier table, object data, SchemaMember member)
        {
            //忽略主键修改,即不能修改主键
            if (member.Token.Property.IsPrimaryKey)
            {
                return;
            }

            //如果不是批量更新,并且当前成员没有改动则返回
            if (!context.IsMultiple && !this.HasChanges(data, member.Name))
            {
                return;
            }

            if (member.Token.Property.IsSimplex)
            {
                var field     = table.CreateField(member.Token);
                var parameter = Expression.Parameter(ParameterExpression.Anonymous, member, field);

                statement.Fields.Add(new FieldValue(field, parameter));
                statement.Parameters.Add(parameter);
            }
            else
            {
                var complex = (IEntityComplexPropertyMetadata)member.Token.Property;

                if (complex.Multiplicity == AssociationMultiplicity.Many)
                {
                    this.BuildUpsertion(statement, member);
                }
                else
                {
                    table = this.Join(statement, member);

                    if (member.HasChildren)
                    {
                        foreach (var child in member.Children)
                        {
                            BuildSchema(context, statement, table, member.Token.GetValue(data), child);
                        }
                    }
                }
            }
        }
Exemple #2
0
        private void BuildSchema(DataUpdateContext context, UpdateStatement statement, TableIdentifier table, object data, SchemaMember member)
        {
            //如果不允许更新主键,则忽略对主键修改的构建
            if (member.Token.Property.IsPrimaryKey && !context.Options.HasBehaviors(UpdateBehaviors.PrimaryKey))
            {
                return;
            }

            //确认指定成员是否有必须的写入值
            var provided = context.Validate(member.Token.Property, out var value);

            //如果不是批量更新,并且指定成员不是必须要生成的且也没有必须写入的值,则返回
            if (!context.IsMultiple && !Utility.IsGenerateRequired(ref data, member.Name) && !provided)
            {
                return;
            }

            if (member.Token.Property.IsSimplex)
            {
                //忽略不可变属性
                if (member.Token.Property.Immutable && !provided)
                {
                    return;
                }

                //创建当前单值属性的对应的字段标识
                var field = table.CreateField(member.Token);

                if (typeof(Operand).IsAssignableFrom(member.Token.MemberType))
                {
                    var operand    = (Operand)member.Token.GetValue(data);
                    var expression = this.OperandConverter.Convert(context, statement, operand);
                    statement.Fields.Add(new FieldValue(field, expression));
                }
                else
                {
                    var parameter = provided ?
                                    Expression.Parameter(field, member, value) :
                                    Expression.Parameter(field, member);

                    statement.Parameters.Add(parameter);

                    //如果当前的数据成员类型为递增步长类型则生成递增表达式
                    if (member.Token.MemberType == typeof(Interval))
                    {
                        /*
                         * 注:默认参数类型为对应字段的类型,而该字段类型可能为无符号数,
                         * 因此当参数类型为无符号数并且步长为负数(递减),则可能导致参数类型转换溢出,
                         * 所以必须将该参数类型重置为有符号整数。
                         */
                        parameter.DbType = System.Data.DbType.Int32;

                        //字段设置项的值为「字段+参数」的加法表达式
                        statement.Fields.Add(new FieldValue(field, field.Add(parameter)));
                    }
                    else
                    {
                        //字段设置项的值即为参数
                        statement.Fields.Add(new FieldValue(field, parameter));
                    }
                }
            }
            else
            {
                //不可变复合属性不支持任何写操作,即在修改操作中不能包含不可变复合属性
                if (member.Token.Property.Immutable)
                {
                    throw new DataException($"The '{member.FullPath}' is an immutable complex(navigation) property and does not support the update operation.");
                }

                var complex = (IDataEntityComplexProperty)member.Token.Property;

                if (complex.Multiplicity == DataAssociationMultiplicity.Many)
                {
                    //注:在构建一对多的导航属性的UPSERT语句时不能指定容器数据(即data参数值为空),因为批量操作语句不支持在构建阶段绑定到具体数据
                    var upserts = UpsertStatementBuilder.BuildUpserts(context, complex.Foreign, null, member, member.Children);

                    //将新建的语句加入到主语句的从属集中
                    foreach (var upsert in upserts)
                    {
                        statement.Slaves.Add(upsert);
                    }
                }
                else
                {
                    if (context.Source.Features.Support(Feature.Updation.Multitable))
                    {
                        this.BuildComplex(context, statement, data, member);
                    }
                    else
                    {
                        this.BuildComplexStandalone(context, statement, data, member);
                    }
                }
            }
        }
Exemple #3
0
        private void BuildSchema(DataUpdateContext context, UpdateStatement statement, TableIdentifier table, object data, SchemaMember member)
        {
            //忽略主键修改,即不能修改主键
            if (member.Token.Property.IsPrimaryKey)
            {
                return;
            }

            //确认指定成员是否有必须的写入值
            var provided = context.Validate(member.Token.Property, out var value);

            //如果不是批量更新,并且指定成员不是必须要生成的且也没有必须写入的值,则返回
            if (!context.IsMultiple && !Utility.IsGenerateRequired(ref data, member.Name) && !provided)
            {
                return;
            }

            if (member.Token.Property.IsSimplex)
            {
                //忽略不可变属性
                if (member.Token.Property.Immutable && !provided)
                {
                    return;
                }

                var field     = table.CreateField(member.Token);
                var parameter = provided ?
                                Expression.Parameter(field, member, value) :
                                Expression.Parameter(field, member);

                //如果当前的数据成员类型为递增步长类型则生成递增表达式
                if (member.Token.MemberType == typeof(Interval))
                {
                    /*
                     * 注:默认参数类型为对应字段的类型,而该字段类型可能为无符号数,
                     * 因此当参数类型为无符号数并且步长为负数(递减),则可能导致参数类型转换溢出,
                     * 所以必须将该参数类型重置为有符号整数。
                     */
                    parameter.DbType = System.Data.DbType.Int32;

                    //字段设置项的值为字段加参数的加法表达式
                    statement.Fields.Add(new FieldValue(field, field.Add(parameter)));
                }
                else
                {
                    statement.Fields.Add(new FieldValue(field, parameter));
                }

                statement.Parameters.Add(parameter);
            }
            else
            {
                //不可变复合属性不支持任何写操作,即在修改操作中不能包含不可变复合属性
                if (member.Token.Property.Immutable)
                {
                    throw new DataException($"The '{member.FullPath}' is an immutable complex(navigation) property and does not support the update operation.");
                }

                var complex = (IDataEntityComplexProperty)member.Token.Property;

                if (complex.Multiplicity == DataAssociationMultiplicity.Many)
                {
                    var upserts = UpsertStatementBuilder.BuildUpserts(context, complex.Foreign, data, member, member.Children);

                    //将新建的语句加入到主语句的从属集中
                    foreach (var upsert in upserts)
                    {
                        statement.Slaves.Add(upsert);
                    }
                }
                else
                {
                    if (context.Source.Features.Support(Feature.Updation.Multitable))
                    {
                        this.BuildComplex(context, statement, data, member);
                    }
                    else
                    {
                        this.BuildComplexStandalone(context, statement, data, member);
                    }
                }
            }
        }