Esempio n. 1
0
        /// <inheritdoc/>
        protected override SqlFragment GenerateForUpdateContent(GenerateContext context, DbExpression content)
        {
            var data = (UpdateContent)context.Data;

            data.SetConcurrencyExpectCount(1);
            RegisterExpressionForCommit(context, content, data.CommitObject);
            UpdateFragment update = null;

            if (data.Items.Count == 1)
            {
                update = data.UpdateByKeys(data.Unit, data.TargetName);
            }
            else
            {
                var values = new ValuesFragment(context, data.CommitObject, data.Items, data.Table);
                RegisterExpressionForCommit(context, content, values);
                update = data.UpdateByTemptable(data.Unit, values, data.TargetName);
            }
            if (data.ReturnMembers.Any())
            {
                foreach (var member in data.ReturnMembers)
                {
                    var metadata = member.Metadata;
                    update.ReturnMembers.Add(update.Target.GetMember(metadata));
                }
                data.GenerateOutput();
            }
            return(update);
        }
Esempio n. 2
0
        /// <summary>
        /// 生成更新单个关系对象语句。
        /// </summary>
        /// <param name="context">生成上下文。</param>
        /// <returns>语句片段。</returns>
        protected virtual SqlFragment GenerateForRelationUpdate(GenerateContext context)
        {
            var data     = (RelationContent)context.Data;
            var metadata = data.Items.Navigate;
            var update   = new UpdateFragment(context, data.Table);

            update.AddSource(update.Target);
            if (data.IsAddRelation)
            {
                var source = data.CommitObject;
                foreach (var pair in metadata.Pairs)
                {
                    update.SetValue(pair.ForeignKey, source.GetMember(pair.PrincipalKey));
                }
            }
            else
            {
                var nullfargment = new SimpleFragment(context, "NULL");
                foreach (var pair in metadata.Pairs)
                {
                    update.SetValue(pair.ForeignKey, nullfargment);
                }
            }
            update.Where = update.Target.JoinCondition(data.CommitObject, data.Table.Keys);
            return(update);
        }
Esempio n. 3
0
        /// <summary>
        /// 使用临时表形式,生成更新若干数据对象语句,
        /// 要求数据库拥有<see cref="EDbCapable.TemporaryTable"/>
        /// 和<see cref="EDbCapable.ModifyJoin"/>两个特性
        /// </summary>
        /// <param name="context">生成上下文。</param>
        /// <param name="content">更新表达式。</param>
        /// <returns>语句片段。</returns>
        protected virtual SqlFragment GenerateForUpdateTempTable(GenerateContext context, DbExpression content)
        {
            var                    data       = (GenerateDataForUpdate)context.Data;
            var                    name       = data.TargetName;
            var                    block      = new BlockFragment(context);
            UpdateFragment         mainUpdate = null;
            TemporaryTableFragment temptable  = null;

            var members = data.GetTables().SelectMany(a => a.Members);

            foreach (var unit in data.GetUnits())
            {
                TemporaryTableFragment current = null;
                if (temptable == null)
                {
                    current = new TemporaryTableFragment(context, members);
                }
                else
                {
                    current = new TemporaryTableFragment(context, temptable.Name, members);
                }
                GenerateForUpdateRegister(context, content, current);

                var metadata = unit.Table;
                var update   = new UpdateFragment(context, metadata, name);
                update.AddSource(update.Target, current);
                GenerateForUpdateMembers(context, unit, update, current);
                update.Target.Join(current, metadata.Keys.Concat(metadata.Concurrencys));
                block.Add(update);
                if (unit == data.MainUnit)
                {
                    mainUpdate = update;
                }
                if (temptable == null)
                {
                    temptable = current;
                }
                else
                {
                    current.Members.ForEach(m => temptable.GetMember(m.Property));
                }
            }
            block.Insert(0, GenerateCreateTemplateTable(context, temptable, data.CommitObject, data.Items));

            if (data.ReturnMembers.Any())
            {
                var target = data.SubUnits == null ? mainUpdate.Target : new InheritFragment(context, data.Table);
                var select = new SelectFragment(context, target);
                select.Members.AddRange(data.ReturnMembers.Select(a => target.GetMember(a.Metadata)));

                var datatable = temptable.Clone();
                select.AddSource(datatable);
                target.Join(datatable, data.Table.Keys);

                block.Add(select);
                data.GenerateOutput();
            }
            data.SetConcurrencyExpectCount(data.TableCount + 1);
            return(block);
        }
Esempio n. 4
0
        /// <summary>
        /// 生成更新单个数据对象语句。
        /// </summary>
        /// <param name="context">生成上下文</param>
        /// <param name="content">更新表达式。</param>
        /// <returns>语句片段。</returns>
        protected virtual SqlFragment GenerateForUpdateSingle(GenerateContext context, DbExpression content)
        {
            var            data       = (GenerateDataForUpdate)context.Data;
            var            block      = new BlockFragment(context);
            UpdateFragment mainUpdate = null;
            var            name       = data.TargetName;

            GenerateForUpdateRegister(context, content, data.CommitObject);
            foreach (var unit in data.GetUnits())
            {
                var metadata = unit.Table;
                var update   = new UpdateFragment(context, metadata, name);
                data.CommitObject.Parent = update;
                GenerateForUpdateMembers(context, unit, update, data.CommitObject);
                update.Where = update.Target.JoinCondition(data.CommitObject, metadata.Keys.Union(metadata.Concurrencys));
                block.Add(update);
                if (unit == data.MainUnit)
                {
                    mainUpdate = update;
                }
            }
            if (data.ReturnMembers.Any())
            {
                var target = data.SubUnits == null ? mainUpdate.Target : new InheritFragment(context, data.Table);
                var select = new SelectFragment(context, target);
                select.Members.AddRange(data.ReturnMembers.Select(a => target.GetMember(a.Metadata)));
                select.Where = target.JoinCondition(data.CommitObject, data.Table.Keys);
                block.Add(select);
                data.GenerateOutput();
            }
            data.SetConcurrencyExpectCount(data.TableCount);
            return(block);
        }
Esempio n. 5
0
        internal static UpdateFragment UpdateByTemptable(this ContentBase data, CommitUnitBase unit, SourceFragment current, DbName name = null)
        {
            var context  = data.GenerateContext;
            var metadata = unit.Table;
            var update   = new UpdateFragment(context, metadata, name);

            update.AddSource(update.Target, current);
            data.SetCommitMembers(update, unit, current);
            update.Target.Join(current, data.UnionConcurrencyMembers(metadata, metadata.Keys));
            return(update);
        }
Esempio n. 6
0
        internal static UpdateFragment UpdateByKeys(this ContentBase data, CommitUnitBase unit, DbName name = null)
        {
            var context  = data.GenerateContext;
            var metadata = unit.Table;
            var update   = new UpdateFragment(context, metadata, name);

            data.CommitObject.Parent = update;
            data.SetCommitMembers(update, unit);
            update.Where = update.Target.JoinCondition(data.CommitObject, data.UnionConcurrencyMembers(metadata, metadata.Keys));
            return(update);
        }
Esempio n. 7
0
        private static void SetCommitMembers(this ContentBase data, UpdateFragment update, CommitUnitBase unit, ISourceFragment source = null)
        {
            source = source ?? data.CommitObject;
            foreach (var member in unit.Members)
            {
                switch (member.ValueType)
                {
                case ECommitValueType.Constant:
                    update.SetValue(member.Metadata, source.GetMember(member.Metadata));
                    break;

                case ECommitValueType.Expression:
                    var exp = (CommitExpressionMember)member;
                    update.SetValue(member.Metadata, update.CreateExpression(exp.Expression));
                    break;
                }
            }
        }
Esempio n. 8
0
        /// <summary>
        /// 生成更新若干关系对象(单个主键)语句。
        /// </summary>
        /// <param name="context">生成上下文。</param>
        /// <returns>语句片段。</returns>
        protected virtual SqlFragment GenerateForRelationDeleteKey(GenerateContext context)
        {
            var data     = (RelationContent)context.Data;
            var metadata = data.Items.Navigate;
            var update   = new UpdateFragment(context, data.Table);

            update.AddSource(update.Target);
            metadata.Pairs.ForEach(
                pair => update.SetValue(pair.ForeignKey, new SimpleFragment(context, "NULL")));
            var member    = new CommitMemberFragment(context, data.Loader, update, data.Table.Keys[0].Member);
            var values    = new ValueListFragment(context, member, data.Items);
            var keyMember = update.Target.GetMember(data.Table.Keys[0]);

            update.Where = new ScalarFragment(context, values, keyMember)
            {
                Function = SupportMembers.Enumerable.Contains
            };
            return(update);
        }
Esempio n. 9
0
        /// <inheritdoc/>
        protected override SqlFragment GenerateForRelation(GenerateContext context, DbExpression content)
        {
            var data = (RelationContent)context.Data;

            if (data.Items.Count > 1)
            {
                var metadata = data.Items.Navigate;
                if (data.IsAddRelation && !metadata.IsComposite)
                {
                    var columns = data.Source.Keys.Concat(metadata.Pairs.Select(a => a.ForeignKey));
                    var values  = new ValuesFragment(context, data.CommitObject, data.Items);
                    data.Source.Keys.ForEach(key => values.SetValue(key));
                    if (data.IsAddRelation)
                    {
                        metadata.Pairs.ForEach(
                            pair => values.SetValue(pair.ForeignKey, data.CommitObject.GetMember(pair.PrincipalKey)));
                    }
                    var update = new UpdateFragment(context, data.Table);
                    update.AddSource(update.Target, values);
                    foreach (var pair in metadata.Pairs)
                    {
                        update.SetValue(pair.ForeignKey, values.GetMember(pair.ForeignKey));
                    }
                    update.Target.Join(values, data.Table.Keys);
                    return(update);
                }
                else if (!data.IsAddRelation && metadata.IsComposite)
                {
                    var composite = (CompositeNavigateMetadata)data.Items.Navigate;
                    var values    = new ValuesFragment(context, data.CommitObject, data.Items);
                    composite.Pairs.ForEach(pair => values.SetValue(pair.ForeignKey, data.CommitObject.GetMember(pair.PrincipalKey)));
                    composite.CompositePairs.ForEach(pair => values.SetValue(pair.ForeignKey, data.CommitObject.GetMember(pair.PrincipalKey)));
                    var target = new TableFragment(context, data.Table);
                    var delete = new DeleteFragment(context, target);
                    delete.AddSource(values);
                    target.Join(values, composite.Pairs.Select(a => a.ForeignKey).Concat(composite.CompositePairs.Select(a => a.ForeignKey)));
                    return(delete);
                }
            }
            return(base.GenerateForRelation(context, content));
        }
Esempio n. 10
0
        private SqlFragment GenerateForInsertIdentityMultipleRepeat(GenerateContext context, CommitIdentityUnit mainunit, ColumnMetadata rowindex,
                                                                    TemporaryTableFragment temporaryTable, RowIndexFragment rowindexfragment, GenerateDataForInsert data, out TableFragment whileTarget)
        {
            var repeatfragment = new RepeatBlockFragment(context, data.Items);
            var block          = repeatfragment.Block;
            var whileInsert    = context.Insert(temporaryTable, mainunit.Table,
                                                mainunit.Members.Where(a => a.ValueType != ECommitValueType.Database).Select(a => a.Metadata));
            var whileSelect = (QueryBaseFragment)whileInsert.Query;

            whileSelect.Where = context.Equal(temporaryTable.GetMember(rowindex), new RowIndexFragment(context));
            block.Add(whileInsert);
            var whileUpdate = new UpdateFragment(context, temporaryTable);
            var getidentity = whileUpdate.CreateExpression(
                context.Translate(Expression.Call(null, SupportMembers.DbFunctions.GetIdentity)));

            whileUpdate.SetValue(mainunit.Identity.Metadata, getidentity);
            whileUpdate.Where = context.Equal(temporaryTable.GetMember(rowindex), new RowIndexFragment(context));
            block.Add(whileUpdate);
            whileTarget = (TableFragment)whileInsert.Target;
            return(repeatfragment);
        }
Esempio n. 11
0
        private WhileFragment GenerateForInsertIdentityMultipleWhile(GenerateContext context, CommitIdentityUnit mainunit, CreateVariableFragment index,
                                                                     ColumnMetadata rowindex, TemporaryTableFragment temporaryTable, RowIndexFragment rowindexfragment, out TableFragment whileTarget)
        {
            var whilefragment = new WhileFragment(context, context.LessThan(index.Name, rowindexfragment));
            var block         = whilefragment.Block;
            var whileInsert   = context.Insert(temporaryTable, mainunit.Table,
                                               mainunit.Members.Where(a => a.ValueType != ECommitValueType.Database).Select(a => a.Metadata));
            var whileSelect = (QueryBaseFragment)whileInsert.Query;

            whileSelect.Where = context.Equal(temporaryTable.GetMember(rowindex), index.Name);
            block.Add(whileInsert);
            var whileUpdate = new UpdateFragment(context, temporaryTable);
            var getidentity = whileUpdate.CreateExpression(
                context.Translate(Expression.Call(null, SupportMembers.DbFunctions.GetIdentity)));

            whileUpdate.SetValue(mainunit.Identity.Metadata, getidentity);
            whileUpdate.Where = context.Equal(temporaryTable.GetMember(rowindex), index.Name);
            block.Add(whileUpdate);
            block.Add(context.Assign(index.Name, context.Add(index.Name, context.StatementString("1"))));
            whileTarget = (TableFragment)whileInsert.Target;
            return(whilefragment);
        }
Esempio n. 12
0
        /// <summary>
        /// 使用临时表形式,生成更新关系语句,
        /// 要求数据库拥有<see cref="EDbCapable.TemporaryTable"/>
        /// 和<see cref="EDbCapable.ModifyJoin"/>两个特性。
        /// </summary>
        /// <param name="context">生成上下文。</param>
        /// <returns>语句片段。</returns>
        protected virtual SqlFragment GenerateForRelationUpdateTempTable(GenerateContext context)
        {
            var data            = (RelationContent)context.Data;
            var metadata        = data.Items.Navigate;
            var block           = new BlockFragment(context);
            var createtemptable = new CreateTempTableFragment(context,
                                                              data.IsAddRelation ? data.Source.Keys.Concat(metadata.Pairs.Select(a => a.ForeignKey)) : data.Source.Keys);
            var insert = new InsertValueFragment(context, createtemptable.Table, data.CommitObject, data.Items);

            data.Source.Keys.ForEach(key => insert.SetValue(key));
            if (data.IsAddRelation)
            {
                metadata.Pairs.ForEach(
                    pair => insert.SetValue(pair.ForeignKey, data.CommitObject.GetMember(pair.PrincipalKey)));
            }
            var temptable = createtemptable.Table;
            var update    = new UpdateFragment(context, data.Table);

            update.AddSource(update.Target, temptable);
            if (data.IsAddRelation)
            {
                foreach (var pair in metadata.Pairs)
                {
                    update.SetValue(pair.ForeignKey, temptable.GetMember(pair.ForeignKey));
                }
            }
            else
            {
                var nullfargment = new SimpleFragment(context, "NULL");
                foreach (var pair in metadata.Pairs)
                {
                    update.SetValue(pair.ForeignKey, nullfargment);
                }
            }
            update.Target.Join(temptable, data.Table.Keys);
            return(new BlockFragment(context, createtemptable, insert, update));
        }
Esempio n. 13
0
        /// <summary>
        /// 表达式生成更新语句。
        /// </summary>
        /// <param name="context">生成上下文。</param>
        /// <param name="content">生成表达式。</param>
        /// <returns>语句片段。</returns>
        protected virtual SqlFragment GenerateForUpdateStatement(GenerateContext context, DbExpression content)
        {
            SourceFragment GetRootSource(ISourceFragment query)
            {
                if (query is SelectFragment select)
                {
                    return(GetRootSource(select.Sources.FirstOrDefault()));
                }
                else if (query is TableFragment || query is InheritFragment)
                {
                    return((SourceFragment)query);
                }
                return(null);
            }

            var data     = (StatementContent)context.Data;
            var newitem  = (DbNewExpression)data.ItemEpxression;
            var source   = CreateSource(context, content) as QueryBaseFragment;
            var metadata = data.Table;

            if (metadata.InheritSets.Length == 0)
            {
                TableFragment target = GetRootSource(source) as TableFragment;
                if (target == null)
                {
                    target = new TableFragment(context, metadata, data.TargetName);
                }
                var update = new UpdateFragment(context, target)
                {
                    Where = source.Where,
                    Take  = source.Take
                };
                update.AddSource(source.Sources);
                foreach (var item in newitem.Members)
                {
                    update.SetValue(metadata.Members[(PropertyInfo)item.Key], update.CreateExpression(item.Value));
                }
                return(update);
            }
            else
            {
                var allmembers = metadata.InheritSets.SelectMany(a => a.Members)
                                 .Concat(metadata.Members).ToDictionary(a => a.Member, a => a);
                InheritFragment inherit = GetRootSource(source) as InheritFragment;
                if (inherit == null)
                {
                    inherit = new InheritFragment(context, metadata);
                }
                var updates = inherit.Tables.ToDictionary(a => a.Metadata, a =>
                {
                    var target = inherit.Tables.Single(b => b.Metadata == a.Metadata);
                    var update = new UpdateFragment(context, target)
                    {
                        Where = source.Where,
                        Take  = source.Take
                    };
                    update.AddSource(source.Sources);
                    return(update);
                });
                foreach (var item in newitem.Members)
                {
                    var column = allmembers[(PropertyInfo)item.Key];
                    var update = updates[column.Table];
                    foreach (var s in source.Sources)
                    {
                        s.Parent = update;
                    }
                    update.SetValue(column, update.CreateExpression(item.Value));
                }
                var block = new BlockFragment(context);
                block.Add(updates.Values.Where(a => a.Values.Any()).OfType <ISqlFragment>());
                return(block);
            }
        }
Esempio n. 14
0
        //生成更新表达式。
        private void GenerateForUpdateMembers(GenerateContext context, CommitUnitBase unit, UpdateFragment update, ISourceFragment source)
        {
            foreach (var member in unit.Members)
            {
                switch (member.ValueType)
                {
                case ECommitValueType.Constant:
                    update.SetValue(member.Metadata, source.GetMember(member.Metadata));
                    break;

                case ECommitValueType.Expression:
                    var exp = (CommitExpressionMember)member;
                    update.SetValue(member.Metadata, update.CreateExpression(exp.Expression));
                    break;
                }
            }
        }