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