示例#1
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);
            }
        }
示例#2
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);
        }
示例#3
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);
        }
示例#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);
        }
示例#5
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);
        }
        /// <summary>
        /// 生成删除单个数据对象语句
        /// </summary>
        /// <param name="context">生成上下文</param>
        /// <returns>语句片段。</returns>
        protected virtual SqlFragment GenerateForDeleteSingle(GenerateContext context)
        {
            var data  = (GenerateDataForDelete)context.Data;
            var block = new BlockFragment(context);
            var name  = data.TargetName;

            foreach (var table in data.GetTables())
            {
                var delete = new DeleteFragment(context, table, name);
                delete.Where = delete.Target.JoinCondition(data.CommitObject, table.Keys.Union(table.Concurrencys));
                block.Add(delete);
            }
            data.SetConcurrencyExpectCount(data.TableCount);
            return(block);
        }
示例#7
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);
            }
        }
示例#8
0
        /// <summary>
        /// 生成插入若干数据对象语句。
        /// </summary>
        /// <param name="context">生成上下文。</param>
        /// <returns>语句片段。</returns>
        protected virtual SqlFragment GenerateForInsertSimple(GenerateContext context)
        {
            var data     = (GenerateDataForInsert)context.Data;
            var name     = data.TargetName;
            var block    = new BlockFragment(context);
            var mainunit = (CommitKeyUnit)data.MainUnit;
            InsertValueFragment mainInsert = null;

            foreach (var unit in data.GetUnits().OfType <CommitKeyUnit>())
            {
                var target = new TableFragment(context, unit.Table, name);
                var insert = new InsertValueFragment(context, target, data.CommitObject, data.Items);
                data.CommitObject.Parent = insert;
                unit.Keys.Concat(unit.Members).ForEach(member => GenerateForInsertMembers(insert, member));
                block.Add(insert);
                mainInsert = insert;
            }
            GenerateForInsertReturnStatement(context, block, mainInsert.Target, null);
            return(block);
        }
        /// <summary>
        /// 生成删除若干数据对象(单个主键)语句。
        /// </summary>
        /// <param name="context">生成上下文。</param>
        /// <returns>语句片段。</returns>
        protected virtual SqlFragment GenerateForDeleteKey(GenerateContext context)
        {
            var data   = (GenerateDataForDelete)context.Data;
            var block  = new BlockFragment(context);
            var key    = data.Table.Keys[0];
            var member = (CommitMemberFragment)data.CommitObject.GetMember(key);
            var values = new ValueListFragment(context, member, data.Items);
            var name   = data.TargetName;

            foreach (var table in data.GetTables())
            {
                var delete    = new DeleteFragment(context, table, name);
                var keyMember = delete.Target.GetMember(key);
                delete.Where = new ScalarFragment(context, values, keyMember)
                {
                    Function = SupportMembers.Enumerable.Contains
                };
                block.Add(delete);
            }
            return(block);
        }
示例#10
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);
            }
        }
        /// <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);
        }
示例#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));
        }
示例#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);
            }
        }
示例#14
0
        /// <summary>
        /// 生成插入单个数据对象语句,对象的主键是标识列。
        /// </summary>
        /// <param name="context">生成上下文。</param>
        /// <returns>语句片段。</returns>
        protected virtual SqlFragment GenerateForInsertIdentitySingle(GenerateContext context)
        {
            var getidentity = context.Translate(Expression.Call(null, SupportMembers.DbFunctions.GetIdentity));

            var data           = (GenerateDataForInsert)context.Data;
            var identityunit   = (CommitIdentityUnit)data.MainUnit;
            var keyVars        = new Dictionary <ColumnMetadata, VariableFragment>();
            var identityCreate = new CreateVariableFragment(context, identityunit.Identity.Metadata.Member.PropertyType);

            keyVars.Add(identityunit.Identity.Metadata, identityCreate.Name);
            var block = new BlockFragment(context);

            if (!context.Feature.HasCapable(EDbCapable.ImplicitDeclareVariable))
            {
                block.Add(identityCreate);
            }
            var name       = data.TargetName;
            var maintarget = new TableFragment(context, identityunit.Table, name);

            {
                var insert = new InsertValueFragment(context, maintarget, data.CommitObject, data.Items);
                data.CommitObject.Parent = insert;
                identityunit.Members.ForEach(member =>
                {
                    if (member.Metadata.IsKey && member.ValueType == ECommitValueType.Expression)
                    {
                        var expMember = (CommitExpressionMember)member;
                        var exp       = insert.CreateExpression(expMember.Expression);
                        var expVar    = new CreateVariableFragment(context, member.Metadata.Member.PropertyType);
                        block.Add(expVar);
                        block.Add(context.Assign(expVar.Name, exp));
                        keyVars.Add(member.Metadata, expVar.Name);
                    }
                    else
                    {
                        GenerateForInsertMembers(insert, member);
                    }
                });
                block.Add(insert);
                block.Add(context.Assign(identityCreate.Name, insert.CreateExpression(getidentity)));
            }
            if (data.SubUnits != null)
            {
                foreach (var unit in data.SubUnits)
                {
                    var target = new TableFragment(context, unit.Table);
                    var insert = new InsertValueFragment(context, target, data.CommitObject, data.Items);
                    data.CommitObject.Parent = insert;
                    unit.Keys.ForEach(member =>
                    {
                        if (keyVars.TryGetValue(member.Metadata, out VariableFragment value))
                        {
                            insert.SetValue(member.Metadata, value);
                        }
                        else
                        {
                            GenerateForInsertMembers(insert, member);
                        }
                    });
                    unit.Members.ForEach(member => GenerateForInsertMembers(insert, member));
                    block.Add(insert);
                }
            }
            if (data.ReturnMembers.Any())
            {
                ISourceFragment target = maintarget;
                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)));
                select.Where = data.Table.Keys.Select(key => context.Equal(target.GetMember(key),
                                                                           keyVars.ContainsKey(key) ? (IExpressionFragment)keyVars[key] : data.CommitObject.GetMember(key))).Merge();
                block.Add(select);
            }
            return(block);
        }