示例#1
0
        protected override Expression VisitMemberInit(MemberInitExpression node)
        {
            ExpansionOptions expansion = expansions.First();

            if (node.NewExpression.Type != expansion.ParentType)
            {
                return(base.VisitMemberInit(node));
            }

            return(Expression.MemberInit
                   (
                       Expression.New(node.Type),
                       node.Bindings.OfType <MemberAssignment>().Aggregate
                       (
                           new List <MemberBinding>(),
                           AddBinding
                       )
                   ));

            List <MemberBinding> AddBinding(List <MemberBinding> list, MemberAssignment binding)
            {
                if (ListTypesAreEquivalent(binding.Member.GetMemberType(), expansion.MemberType) &&
                    string.Compare(binding.Member.Name, expansion.MemberName, true) == 0)       //found the expansion
                {
                    if (foundExpansions.Count > 0)
                    {
                        throw new NotSupportedException("Recursive queries not supported");
                    }

                    AddBindingExpression(GetBindingExpression(binding, expansion));
                }
                else
                {
                    list.Add(binding);
                }

                return(list);

                void AddBindingExpression(Expression bindingExpression)
                {
                    list.Add(Expression.Bind(binding.Member, bindingExpression));
                    foundExpansions.Add(bindingExpression);
                }
            }
        }
示例#2
0
 protected override Expression GetBindingExpression(MemberAssignment binding, ExpansionOptions expansion)
 {
     if (expansion.QueryOption != null)
     {
         return(QueryFunctionAppender.AppendQueryMethod(binding.Expression, expansion, mapper));
     }
     else if (expansions.Count > 1)  //Mutually exclusive with expansion.QueryOption != null.
     {                               //There can be only one set of QueryOptions in the list.
         return(UpdaterExpansion
                (
                    binding.Expression,
                    expansions.Skip(1).ToList(),
                    mapper
                ));
     }
     else
     {
         throw new ArgumentException("Last expansion in the list must have a filter", nameof(expansions));
     }
 }
示例#3
0
 public bool Equals(ExpansionOptions other)
 {
     return(Value == other.Value);
 }
示例#4
0
 public static Expression AppendQueryMethod(Expression expression, ExpansionOptions expansion, IMapper mapper)
 => new QueryFunctionAppender(expression, expansion, mapper).Visit(expression);
示例#5
0
 public QueryFunctionAppender(Expression expression, ExpansionOptions expansion, IMapper mapper)
 {
     this.expansion  = expansion;
     this.expression = expression;
     this.mapper     = mapper;
 }
示例#6
0
        private TREENODE ExpandTreeNode(
            TREENODE parentNode, TREENODE startNode, int row, int column, ObjectStyle branchStyle, bool insertNewChild,
            out ExpansionOptions expansionOptions, out int itemIncr, out bool requireInitialSubItemExpansion)
        {
            TREENODE tnCur;
            TREENODE tn1;
            TREENODE tn2;
            TREENODE newChildNode = null;
            // Don't test expandable while loading a complex column, the request can be ambiguous.
            // Just go ahead and fire off the request. A null return will leave the cell as a simple item.
            Debug.Assert(
                branchStyle == ObjectStyle.SubItemRootBranch || parentNode.Branch.IsExpandable(row, column),
                "GetExpandable should be called before this is attempted");
            IBranch newBranch;
            try
            {
                SetStateFlag(TreeStateFlags.InExpansion, true);
                var options = 0;
                newBranch = parentNode.Branch.GetObject(row, column, branchStyle, ref options) as IBranch;
                expansionOptions = (ExpansionOptions)options;
            }
            finally
            {
                SetStateFlag(TreeStateFlags.InExpansion, false);
            }

            itemIncr = 0;
            requireInitialSubItemExpansion = false;
            newChildNode = null;
            if (newBranch != null)
            {
                itemIncr = newBranch.VisibleItemCount; //ExpansionCount can be 0 on success, don't check
                // UNDONE_MC: Only allow multi-column children if the parent branch does,
                // or if this is the root node of a complex item in the last column of a tree.
                var allowMultiColumn = true;
                tnCur = CreateTreeNode(startNode, newBranch, this, allowMultiColumn, parentNode.InSubItemColumn, parentNode.MultiColumn);
                tnCur.Index = row;
                tnCur.ImmedCount = tnCur.FullCount = itemIncr;
                if (allowMultiColumn
                    && tnCur.MultiColumn
                    && tnCur.ComplexColumns)
                {
                    requireInitialSubItemExpansion = true;
                }
                tnCur.Expanded = true;
                tnCur.AllowRecursion = (expansionOptions & ExpansionOptions.BlockRecursion) == 0;
                tnCur.UpdateDelayed = false;
                tnCur.Parent = parentNode;
                if (tnCur.Dynamic)
                {
                    AddTrackedNode(newBranch, tnCur);
                }
                newChildNode = tnCur;
                if (insertNewChild && startNode == null)
                {
                    //Place node in proper position in child chain based on index
                    tn1 = parentNode.FirstChild;
                    tn2 = null;
                    if (tn1 != null)
                    {
                        while (row >= tn1.Index)
                        {
                            Debug.Assert(tn1.Index != row, "TrackIndex screwed up");
                            tn2 = tn1;
                            if (null == (tn1 = tn2.NextSibling))
                            {
                                break;
                            }
                        }
                        if (tn2 != null)
                        {
                            tn2.NextSibling = tnCur;
                        }
                        else
                        {
                            parentNode.FirstChild = tnCur;
                        }
                        tnCur.NextSibling = tn1; //tn1 May be null, not worth the check
                    }
                    else
                    {
                        parentNode.FirstChild = tnCur;
                    }
                }
            }
            return newChildNode;
        }
示例#7
0
 private TREENODE ExpandTreeNode(
     TREENODE parentNode, TREENODE startNode, int row, int column, ObjectStyle branchStyle, bool insertNewChild,
     out ExpansionOptions expansionOptions, out int itemIncr, out int subItemIncr)
 {
     bool requireInitialSubItemExpansion;
     subItemIncr = 0;
     var retVal = ExpandTreeNode(
         parentNode,
         startNode,
         row,
         column,
         branchStyle,
         insertNewChild,
         out expansionOptions,
         out itemIncr,
         out requireInitialSubItemExpansion);
     if (retVal != null && requireInitialSubItemExpansion)
     {
         try
         {
             // UNDONE_MC: The full subitem gain will be higher than the immediate
             // gain if the expanded items are also complex
             ExpandInitialComplexSubItems(retVal as TREENODE_Multi, out subItemIncr);
         }
         catch (Exception ex)
         {
             Debug.Assert(false, ex.Message, ex.StackTrace);
             // Swallow this exception. The tree is left in a very bad state
             // if we get this far into an expansion and then throw.
         }
         finally
         {
             // These values may be positive already set if startnode is set,
             // so increment instead of blindly setting to subItemIncr.
             retVal.FullSubItemGain += subItemIncr;
         }
     }
     return retVal;
 }
 public static Expression AppendFilter(Expression expression, ExpansionOptions expansion, IMapper mapper)
 => new FilterAppender(expression, expansion, mapper).Visit(expression);
 public FilterAppender(Expression expression, ExpansionOptions expansion, IMapper mapper)
 {
     this.expansion  = expansion;
     this.expression = expression;
     this.mapper     = mapper;
 }
示例#10
0
 protected abstract Expression GetBindingExpression(MemberAssignment binding, ExpansionOptions expansion);