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); } }
/// <summary> /// 根据指定类型<see cref="DbDataSetExpression"/>表达式创建数据源语句片段。 /// </summary> /// <param name="context">生成上下文。</param> /// <param name="expression">指定表达式。</param> /// <returns>创建结果。</returns> protected virtual ISourceFragment CreateSourceForDataSet(GenerateContext context, DbExpression expression) { var content = (DbDataSetExpression)expression; var metadata = context.Metadata.Table(content.Item.ClrType); SourceFragment table = null; if (metadata.InheritSets.Length > 0) { if (content.Name != null) { throw new NotSupportedException(Res.NotSupportedInheritSetUsingDbName); } table = new InheritFragment(context, metadata); } else { table = new TableFragment(context, content); } context.RegisterSource(content.Item, table); context.RegisterSource(content, table); if (IsSelectFragment(content)) { return(InitialSelectFragment(new SelectFragment(context, table), content)); } if (table is InheritFragment inherit) { inherit.Initialize(); } return(table); }
/// <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); } }
/// <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); }