Пример #1
0
        /// <summary>
        /// 使用临时表形式,生成删除若干数据对象(多个主键)语句,
        /// 要求数据库拥有<see cref="EDbCapable.TemporaryTable"/>
        /// 和<see cref="EDbCapable.ModifyJoin"/>两个特性。
        /// </summary>
        /// <param name="context">生成上下文。</param>
        /// <returns>语句片段。</returns>
        protected virtual SqlFragment GenerateForInsertTempTable(GenerateContext context)
        {
            var data        = (GenerateDataForInsert)context.Data;
            var members     = data.GetTables().SelectMany(a => a.Members);
            var createtable = new CreateTempTableFragment(context, members);
            var temptable   = createtable.Table;

            var insert   = new InsertValueFragment(context, temptable, data.CommitObject, data.Items);
            var mainunit = (CommitKeyUnit)data.MainUnit;

            mainunit.Keys.ForEach(member => GenerateForInsertMembers(insert, member));
            data.CommitObject.Parent = insert;
            foreach (var unit in data.GetUnits())
            {
                unit.Members.ForEach(member => GenerateForInsertMembers(insert, member));
            }
            var block = new BlockFragment(context, createtable, insert);

            InsertFragment mainInsert = null;

            foreach (var unit in data.GetUnits().OfType <CommitKeyUnit>())
            {
                mainInsert = context.Insert(temptable, unit);
                block.Add(mainInsert);
            }
            GenerateForInsertReturnStatement(context, block, mainInsert.Target, temptable);
            return(block);
        }
Пример #2
0
        /// <summary>
        /// 使用临时表形式,生成插入单个数据对象语句,对象的主键是标识列,
        /// 要求数据库拥有<see cref="EDbCapable.TemporaryTable"/>
        /// 和<see cref="EDbCapable.ModifyJoin"/>两个特性。
        /// </summary>
        /// <param name="context">生成上下文。</param>
        /// <returns>语句片段。</returns>
        protected virtual SqlFragment GenerateForInsertIdentityTempTable(GenerateContext context)
        {
            var data     = (GenerateDataForInsert)context.Data;
            var mainunit = (CommitIdentityUnit)data.MainUnit;
            var members  = data.GetTables().SelectMany(a => a.Members).ToList();
            var rowindex = new ColumnMetadata(data.Table, SupportMembers.DbMembers.CustomRowIndex,
                                              members.Select(a => a.Name).Unique("RowIndex"));

            members.Add(rowindex);

            var createtable = new CreateTempTableFragment(context, members);
            var temptable   = createtable.Table;

            var insert = new InsertValueFragment(context, temptable, data.CommitObject, data.Items);

            data.CommitObject.Parent = insert;
            foreach (var unit in data.GetUnits())
            {
                unit.Members.ForEach(member => GenerateForInsertMembers(insert, member));
            }
            insert.SetValue(mainunit.Identity.Metadata, new SimpleFragment(context, "0"));
            var rowindexfragment = new RowIndexFragment(context);

            insert.SetValue(rowindex, rowindexfragment);


            TableFragment whileTarget = null;
            BlockFragment block       = null;

            if (context.Feature.HasCapable(EDbCapable.ExternalCompoundStatement))
            {
                var index         = new CreateVariableFragment(context, typeof(int));
                var whilefragment = GenerateForInsertIdentityMultipleWhile(context, mainunit, index,
                                                                           rowindex, createtable.Table, rowindexfragment, out whileTarget);
                block = new BlockFragment(context, index, createtable, insert,
                                          context.Assign(index.Name, context.StatementString("1")), whilefragment);
            }
            else
            {
                var repeatfragment = GenerateForInsertIdentityMultipleRepeat(context, mainunit,
                                                                             rowindex, createtable.Table, rowindexfragment, data, out whileTarget);
                block = new BlockFragment(context, createtable, insert, repeatfragment);
            }

            if (data.SubUnits != null)
            {
                foreach (var unit in data.SubUnits)
                {
                    block.Add(context.Insert(createtable.Table, unit));
                }
            }
            GenerateForInsertReturnStatement(context, block, whileTarget, createtable.Table);
            return(block);
        }
Пример #3
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);
        }
Пример #4
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);
            }
        }
Пример #5
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);
        }