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