コード例 #1
0
ファイル: ODataUriEvaluator.cs プロジェクト: zhonli/odata.net
        private QueryExpression BuildQueryFromSegments()
        {
            var             segments         = this.currentUri.Segments;
            EntitySet       currentEntitySet = null;
            QueryExpression query            = null;

            foreach (var segment in segments)
            {
                if (segment.SegmentType == ODataUriSegmentType.ServiceRoot || segment == SystemSegment.Count || segment == SystemSegment.EntityReferenceLinks || segment == SystemSegment.Value)
                {
                    continue;
                }
                else if (segment.SegmentType == ODataUriSegmentType.EntitySet)
                {
                    // must be the root query
                    ExceptionUtilities.Assert(query == null, "Cannot have multiple entity set segments in the uri");

                    var entitySetSegment = (EntitySetSegment)segment;
                    query            = CommonQueryBuilder.Root(entitySetSegment.EntitySet.Name, this.Repository.RootDataTypes[entitySetSegment.EntitySet.Name].CreateCollectionType());
                    currentEntitySet = entitySetSegment.EntitySet;
                }
                else if (segment.SegmentType == ODataUriSegmentType.Key)
                {
                    // build the key expression
                    ExceptionUtilities.CheckObjectNotNull(query, "Key expression present in uri before any root segment");
                    var keySegment = (KeyExpressionSegment)segment;
                    var values     = keySegment.IncludedValues.Select(p => new NamedValue(p.Key.Name, p.Value));
                    query = query.Key(values);

                    this.shouldLastSegmentBeSingleton = true;
                }
                else if (segment.SegmentType == ODataUriSegmentType.NavigationProperty)
                {
                    ExceptionUtilities.CheckObjectNotNull(query, "Navigation property present in uri before any root segment");

                    var navigationSegment = (NavigationSegment)segment;
                    query = query.Property(navigationSegment.NavigationProperty.Name);

                    ExceptionUtilities.CheckObjectNotNull(currentEntitySet, "Expected an EntitySet Segment prior to a NavigationSegment");
                    currentEntitySet = currentEntitySet.GetRelatedEntitySet(navigationSegment.NavigationProperty);

                    this.shouldLastSegmentBeSingleton = false;
                }
                else if (segment.SegmentType == ODataUriSegmentType.NamedStream)
                {
                    var namedStreamSegment = (NamedStreamSegment)segment;
                    query = query.Property(namedStreamSegment.Name);

                    this.shouldLastSegmentBeSingleton = false;
                }
                else if (segment.SegmentType == ODataUriSegmentType.EntityType)
                {
                    query = this.AddEntityTypeFilter(currentEntitySet, query, (EntityTypeSegment)segment);
                }
                else if (segment.SegmentType == ODataUriSegmentType.Function)
                {
                    ExceptionUtilities.Assert(query == null, "Cannot have multiple root query segments in the uri");

                    var      serviceOperationSegment = (FunctionSegment)segment;
                    Function serviceOperation        = serviceOperationSegment.Function;
                    var      bodyAnnotation          = serviceOperation.Annotations.OfType <FunctionBodyAnnotation>().SingleOrDefault();
                    ExceptionUtilities.CheckObjectNotNull(bodyAnnotation, "Cannot evaluate function without body annotation");

                    List <QueryExpression> serviceOpArguments = new List <QueryExpression>();
                    foreach (var parameter in serviceOperation.Parameters)
                    {
                        var parameterPrimitiveType = parameter.DataType as PrimitiveDataType;
                        ExceptionUtilities.CheckObjectNotNull(parameterPrimitiveType, "Non primitive parameter types are unsupported");

                        string parameterValue;
                        if (this.currentUri.CustomQueryOptions.TryGetValue(parameter.Name, out parameterValue))
                        {
                            object argValue = this.LiteralConverter.DeserializePrimitive(parameterValue, parameterPrimitiveType.GetFacetValue <PrimitiveClrTypeFacet, Type>(typeof(object)));
                            serviceOpArguments.Add(CommonQueryBuilder.Constant(argValue));
                        }
                        else
                        {
                            serviceOpArguments.Add(CommonQueryBuilder.Null(this.Repository.TypeLibrary.GetDefaultQueryType(parameterPrimitiveType)));
                        }
                    }

                    query = new QueryCustomFunctionCallExpression(
                        this.Repository.TypeLibrary.GetDefaultQueryType(serviceOperation.ReturnType),
                        serviceOperation,
                        bodyAnnotation.FunctionBody,
                        false,
                        false,
                        serviceOpArguments.ToArray());

                    serviceOperation.TryGetExpectedServiceOperationEntitySet(out currentEntitySet);
                }
                else
                {
                    // must be a property segment
                    var propertySegment = segment as PropertySegment;
                    ExceptionUtilities.CheckObjectNotNull(propertySegment, "Uri segments contained unhandled segment type '{0}'", segment.SegmentType);
                    ExceptionUtilities.CheckObjectNotNull(query, "Property present in uri before any root segment");

                    query = query.Property(propertySegment.Property.Name);

                    this.shouldLastSegmentBeSingleton = false;
                }
            }

            return(query);
        }