コード例 #1
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);
        }
コード例 #2
0
        internal static InsertValueFragment InsertTemptable(this ContentBase data, TemporaryTableFragment temptable, IEnumerable <CommitMember> members)
        {
            var context = data.GenerateContext;
            var insert  = new InsertValueFragment(context, temptable, data.CommitObject, data.Items);

            data.CommitObject.Parent = insert;
            members.ForEach(member => SetCommitMember(insert, member));
            return(insert);
        }
コード例 #3
0
        /// <summary>
        /// 创建通过临时博删除的语句片段。
        /// </summary>
        /// <param name="data">内容对象。</param>
        /// <param name="metadata">删除表的元数据。</param>
        /// <param name="temptable">临时表。</param>
        /// <param name="name">指定名称。</param>
        /// <returns>语句片段。</returns>
        internal static DeleteFragment DeleteByTemptable(this ContentBase data
                                                         , TableMetadata metadata, TemporaryTableFragment temptable, DbName name = null)
        {
            var context          = data.GenerateContext;
            var filterMembers    = data.UnionConcurrencyMembers(metadata, metadata.Keys);
            var delete           = new DeleteFragment(context, metadata);
            var current          = delete.Target;
            var currenttemptable = new TemporaryTableFragment(context, filterMembers, temptable.Name);

            delete.AddSource(currenttemptable);
            current.Join(currenttemptable, filterMembers);
            return(delete);
        }
コード例 #4
0
        internal static InsertFragment InsertTemptable(this ContentBase data, TemporaryTableFragment temptable, CommitKeyUnit unit, DbName name = null)
        {
            var members = unit.Keys.Concat(unit.Members).Select(a => a.Metadata);
            var context = data.GenerateContext;
            var table   = new TableFragment(context, unit.Table, name);
            var select  = new SelectFragment(context, temptable);
            var current = new InsertFragment(context, table, select);

            foreach (var member in members)
            {
                select.CreateMember(null, temptable.GetMember(member));
                current.CreateMember(null, member);
            }
            return(current);
        }
コード例 #5
0
        /// <summary>
        /// 表达式生成删除语句。
        /// </summary>
        /// <param name="context">生成上下文。</param>
        /// <param name="content">生成表达式。</param>
        /// <returns>语句片段。</returns>
        protected virtual SqlFragment GenerateForDeleteStatement(GenerateContext context, DbExpression content)
        {
            var data   = (StatementContent)context.Data;
            var item   = data.ItemEpxression;
            var source = CreateSource(context, content) as QueryBaseFragment;

            var table = data.Table;

            if (table.InheritSets.Length == 0)
            {
                var target = (TableFragment)GetSource(context, item);
                target.Name = context.ConvertName(data.TargetName);
                var delete = new DeleteFragment(context, target)
                {
                    Where = source.Where,
                    Take  = source.Take
                };
                delete.AddSource(source.Sources.Where(a => a != target));
                return(delete);
            }
            else
            {
                var createtable = new CreateTempTableFragment(context, table.Keys);
                var insert      = new InsertFragment(context, createtable.Table, source);
                insert.Members.AddRange(createtable.Table.Members);
                foreach (var key in table.Keys)
                {
                    RetrievalMember(context, source, new DbMemberExpression(key.Member, item), null, false);
                }
                var block = new BlockFragment(context, createtable, insert);
                foreach (var subtable in table.InheritSets.Concat(new TableMetadata[] { table }).Reverse())
                {
                    var current   = new TableFragment(context, subtable);
                    var delete    = new DeleteFragment(context, current);
                    var temptable = new TemporaryTableFragment(context, table.Keys, createtable.Table.Name);
                    current.Join(temptable, table.Keys);
                    delete.AddSource(temptable);
                    block.Add(delete);
                }
                return(block);
            }
        }
コード例 #6
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);
        }
コード例 #7
0
        /// <summary>
        /// 生成用于插入的语句片段。
        /// </summary>
        /// <param name="context">生成上下文。</param>
        /// <param name="content">插入表达式。</param>
        /// <returns>生成结果。</returns>
        protected virtual SqlFragment GenerateForInsertStatement(GenerateContext context, DbExpression content)
        {
            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)
            {
                var target = new TableFragment(context, metadata, data.TargetName);
                var insert = new InsertFragment(context, target, source);
                GenerateForInsertStatementMembers(context, newitem, source, insert, member => metadata.Members[member]);
                return(insert);
            }
            else
            {
                var allsource   = metadata.InheritSets.Concat(new TableMetadata[] { metadata });
                var allmembers  = allsource.SelectMany(a => a.Members).ToDictionary(a => a.Member, a => a);
                var createtable = new CreateTempTableFragment(context, newitem.Members.Keys.OfType <PropertyInfo>().Select(a => allmembers[a]));
                var insert      = new InsertFragment(context, createtable.Table, source);
                GenerateForInsertStatementMembers(context, newitem, source, insert, member => allmembers[member]);
                var block = new BlockFragment(context, createtable, insert);
                var query = from a in newitem.Members.Keys.OfType <PropertyInfo>().Select(m => allmembers[m])
                            group a by a.Table into g
                            select new { g.Key, Members = g };
                var prefixMembers = query.First().Members.Where(a => a.IsKey);
                foreach (var g in query)
                {
                    IEnumerable <ColumnMetadata> currentMembers = g.Members;
                    if (g.Key.InheritSets.Length > 0)
                    {
                        currentMembers = prefixMembers.Concat(g.Members);
                    }
                    var current = new TemporaryTableFragment(context, currentMembers, createtable.Table.Name);

                    block.Add(context.Insert(current, g.Key, currentMembers));
                }
                return(block);
            }
        }
コード例 #8
0
        /// <summary>
        /// 使用临时表形式,生成删除若干数据对象(多个主键)语句,
        /// 要求数据库拥有<see cref="EDbCapable.TemporaryTable"/>
        /// 和<see cref="EDbCapable.ModifyJoin"/>两个特性。
        /// </summary>
        /// <param name="context">生成上下文。</param>
        /// <returns>语句片段。</returns>
        protected virtual SqlFragment GenerateForDeleteKeysTempTable(GenerateContext context)
        {
            var data  = (GenerateDataForDelete)context.Data;
            var block = new BlockFragment(context)
            {
                GenerateCreateTemplateTable(context, data.CommitObject, data.Items, data.Table.Keys.Concat(data.ConcurrencyMembers))
            };
            var temptable = ((CreateTempTableFragment)block.First()).Table;
            var name      = data.TargetName;

            foreach (var metadata in data.GetTables())
            {
                var delete           = new DeleteFragment(context, metadata, name);
                var current          = delete.Target;
                var currenttemptable = new TemporaryTableFragment(context, temptable.Name, metadata.Keys.Union(metadata.Concurrencys));
                delete.AddSource(currenttemptable);
                current.Join(currenttemptable, metadata.Keys.Union(metadata.Concurrencys));
                block.Add(delete);
            }
            data.SetConcurrencyExpectCount(data.TableCount + 1);
            return(block);
        }
コード例 #9
0
ファイル: MaintenanceFragment.cs プロジェクト: zyj0021/Mego
 /// <summary>
 /// 初始化创建临时表。
 /// </summary>
 /// <param name="context">生成上下文。</param>
 /// <param name="table">仔在临时表。</param>
 public CreateTempTableFragment(GenerateContext context, TemporaryTableFragment table)
     : base(context)
 {
     Table      = table;
     IsVariable = context.Feature.HasCapable(EDbCapable.TableVariable);
 }
コード例 #10
0
        /// <summary>
        /// 创建通过临时表关联的返回数据语句片段。
        /// </summary>
        /// <param name="unit">内容对象。</param>
        /// <param name="target">目标对象。</param>
        /// <param name="temptable">临时表。</param>
        /// <returns>语句片段。</returns>
        internal static SelectFragment SelectReturns(this IContentUnit unit, ISourceFragment target, TemporaryTableFragment temptable)
        {
            var data    = (ContentBase)unit;
            var context = data.GenerateContext;
            var select  = new SelectFragment(context, target);

            select.Members.AddRange(unit.ReturnMembers.Select(a => target.GetMember(a.Metadata)));

            select.AddSource(temptable);
            target.Join(temptable, data.Table.Keys);
            return(select);
        }
コード例 #11
0
        private void GenerateForInsertReturnStatement(GenerateContext context,
                                                      BlockFragment block, ISourceFragment target, TemporaryTableFragment temptable)
        {
            var data = (GenerateDataForInsert)context.Data;

            if (data.ReturnMembers.Any())
            {
                if (data.SubUnits != null)
                {
                    target = new InheritFragment(context, data.Table);
                }
                var select = new SelectFragment(context, target);
                select.Members.AddRange(data.ReturnMembers.Select(a => target.GetMember(a.Metadata)));
                if (temptable == null)
                {
                    select.Where = target.JoinCondition(data.CommitObject, data.Table.Keys);
                }
                else
                {
                    var datatable = temptable.Clone();
                    select.AddSource(datatable);
                    target.Join(datatable, data.Table.Keys);
                }
                block.Add(select);
            }
        }
コード例 #12
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);
        }