コード例 #1
0
        public static IQueryable <Entity> TranslateLinkedEntityToLinq(XrmFakedContext context, LinkEntity le, IQueryable <Entity> query, ColumnSet previousColumnSet, string linkFromAlias = "")
        {
            var leAlias = string.IsNullOrWhiteSpace(le.EntityAlias) ? le.LinkToEntityName : le.EntityAlias;

            context.EnsureEntityNameExistsInMetadata(le.LinkFromEntityName);
            context.EnsureEntityNameExistsInMetadata(le.LinkToEntityName);

            if (!context.AttributeExistsInMetadata(le.LinkToEntityName, le.LinkToAttributeName))
            {
                OrganizationServiceFaultQueryBuilderNoAttributeException.Throw(le.LinkToAttributeName);
            }

            var inner = context.CreateQuery <Entity>(le.LinkToEntityName);

            //if (!le.Columns.AllColumns && le.Columns.Columns.Count == 0)
            //{
            //    le.Columns.AllColumns = true;   //Add all columns in the joined entity, otherwise we can't filter by related attributes, then the Select will actually choose which ones we need
            //}

            if (string.IsNullOrWhiteSpace(linkFromAlias))
            {
                linkFromAlias = le.LinkFromAttributeName;
            }
            else
            {
                linkFromAlias += "." + le.LinkFromAttributeName;
            }

            switch (le.JoinOperator)
            {
            case JoinOperator.Inner:
            case JoinOperator.Natural:
                query = query.Join(inner,
                                   outerKey => outerKey.KeySelector(linkFromAlias, context),
                                   innerKey => innerKey.KeySelector(le.LinkToAttributeName, context),
                                   (outerEl, innerEl) => outerEl
                                   .JoinAttributes(innerEl, new ColumnSet(true), leAlias, context));

                break;

            case JoinOperator.LeftOuter:
                query = query.GroupJoin(inner,
                                        outerKey => outerKey.KeySelector(le.LinkFromAttributeName, context),
                                        innerKey => innerKey.KeySelector(le.LinkToAttributeName, context),
                                        (outerEl, innerElemsCol) => new { outerEl, innerElemsCol })
                        .SelectMany(x => x.innerElemsCol.DefaultIfEmpty()
                                    , (x, y) => x.outerEl
                                    .JoinAttributes(y, new ColumnSet(true), leAlias, context));


                break;

            default:     //This shouldn't be reached as there are only 3 types of Join...
                throw new PullRequestException(string.Format("The join operator {0} is currently not supported. Feel free to implement and send a PR.", le.JoinOperator));
            }

            //Process nested linked entities recursively
            foreach (LinkEntity nestedLinkedEntity in le.LinkEntities)
            {
                if (string.IsNullOrWhiteSpace(le.EntityAlias))
                {
                    le.EntityAlias = le.LinkToEntityName;
                }

                query = TranslateLinkedEntityToLinq(context, nestedLinkedEntity, query, le.Columns, le.EntityAlias);
            }
            return(query);
        }