/// <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); }
/// <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); }
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); }
/// <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); } }
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); }