/// <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));
        }
Beispiel #3
0
        /// <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));
        }