/// <summary> /// 创建通过临时博删除的语句片段。 /// </summary> /// <param name="data">内容对象。</param> /// <param name="metadata">删除表的元数据。</param> /// <param name="temptable">临时表。</param> /// <param name="name">指定名称。</param> /// <returns>语句片段。</returns> internal static DeleteFragment DeleteByTemptable(this ContentBase data , TableMetadata metadata, TemporaryTableFragment temptable, DbName name = null) { var context = data.GenerateContext; var filterMembers = data.UnionConcurrencyMembers(metadata, metadata.Keys); var delete = new DeleteFragment(context, metadata); var current = delete.Target; var currenttemptable = new TemporaryTableFragment(context, filterMembers, temptable.Name); delete.AddSource(currenttemptable); current.Join(currenttemptable, filterMembers); return(delete); }
/// <inheritdoc/> protected override SqlFragment GenerateForDeleteContent(GenerateContext context, DbExpression content) { var data = (DeleteContent)context.Data; data.SetConcurrencyExpectCount(1); var metadata = data.Table; if (data.Items.Count > 1 && metadata.Keys.Length > 1) { var values = new ValuesFragment(context, data.CommitObject, data.Items, data.Table); var filterMembers = data.UnionConcurrencyMembers(metadata, metadata.Keys); var delete = new DeleteFragment(context, metadata); var current = delete.Target; delete.AddSource(values); current.Join(values, filterMembers); return(delete); } return(base.GenerateForDeleteContent(context, content)); }
/// <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); } }
/// <summary> /// 使用临时表形式,生成删除多个复合关系的语句, /// 要求数据库拥有<see cref="EDbCapable.TemporaryTable"/> /// 和<see cref="EDbCapable.ModifyJoin"/>两个特性。 /// </summary> /// <param name="context">生成上下文。</param> /// <returns>语句片段。</returns> protected virtual SqlFragment GenerateForRelationDeleteTempTable(GenerateContext context) { var data = (RelationContent)context.Data; var composite = (CompositeNavigateMetadata)data.Items.Navigate; var createtemptable = new CreateTempTableFragment(context, composite.Pairs.Select(a => a.ForeignKey).Concat(composite.CompositePairs.Select(a => a.ForeignKey))); var insert = new InsertValueFragment(context, createtemptable.Table, data.CommitObject, data.Items); composite.Pairs.ForEach(pair => insert.SetValue(pair.ForeignKey, data.CommitObject.GetMember(pair.PrincipalKey))); composite.CompositePairs.ForEach(pair => insert.SetValue(pair.ForeignKey, data.CommitObject.GetMember(pair.PrincipalKey))); var temptable = createtemptable.Table; var target = new TableFragment(context, data.Table); var delete = new DeleteFragment(context, target); delete.AddSource(temptable); target.Join(temptable, composite.Pairs.Select(a => a.ForeignKey).Concat(composite.CompositePairs.Select(a => a.ForeignKey))); return(new BlockFragment(context, createtemptable, insert, delete)); }
/// <inheritdoc/> protected override SqlFragment GenerateForRelation(GenerateContext context, DbExpression content) { var data = (RelationContent)context.Data; if (data.Items.Count > 1) { var metadata = data.Items.Navigate; if (data.IsAddRelation && !metadata.IsComposite) { var columns = data.Source.Keys.Concat(metadata.Pairs.Select(a => a.ForeignKey)); var values = new ValuesFragment(context, data.CommitObject, data.Items); data.Source.Keys.ForEach(key => values.SetValue(key)); if (data.IsAddRelation) { metadata.Pairs.ForEach( pair => values.SetValue(pair.ForeignKey, data.CommitObject.GetMember(pair.PrincipalKey))); } var update = new UpdateFragment(context, data.Table); update.AddSource(update.Target, values); foreach (var pair in metadata.Pairs) { update.SetValue(pair.ForeignKey, values.GetMember(pair.ForeignKey)); } update.Target.Join(values, data.Table.Keys); return(update); } else if (!data.IsAddRelation && metadata.IsComposite) { var composite = (CompositeNavigateMetadata)data.Items.Navigate; var values = new ValuesFragment(context, data.CommitObject, data.Items); composite.Pairs.ForEach(pair => values.SetValue(pair.ForeignKey, data.CommitObject.GetMember(pair.PrincipalKey))); composite.CompositePairs.ForEach(pair => values.SetValue(pair.ForeignKey, data.CommitObject.GetMember(pair.PrincipalKey))); var target = new TableFragment(context, data.Table); var delete = new DeleteFragment(context, target); delete.AddSource(values); target.Join(values, composite.Pairs.Select(a => a.ForeignKey).Concat(composite.CompositePairs.Select(a => a.ForeignKey))); return(delete); } } return(base.GenerateForRelation(context, content)); }
/// <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); }