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