示例#1
0
        /// <summary>
        /// Return the collection of links as ODataEntityReferenceLink instances
        /// </summary>
        /// <param name="elements">Elements whose uri need to be written out.</param>
        /// <param name="linksCollection">LinkCollection instance which represents the collection getting written out.</param>
        /// <returns>Return the collection of links as ODataEntityReferenceLink instances.</returns>
        private IEnumerable <ODataEntityReferenceLink> GetLinksCollection(QueryResultInfo elements, ODataEntityReferenceLinks linksCollection)
        {
            object          lastObject            = null;
            IExpandedResult lastExpandedSkipToken = null;

            while (elements.HasMoved)
            {
                object          element   = elements.Current;
                IExpandedResult skipToken = null;
                if (element != null)
                {
                    IExpandedResult expanded = element as IExpandedResult;
                    if (expanded != null)
                    {
                        element   = GetExpandedElement(expanded);
                        skipToken = this.GetSkipToken(expanded);
                    }
                }

                this.IncrementSegmentResultCount();
                yield return(new ODataEntityReferenceLink {
                    Url = this.GetEntityEditLink(element)
                });

                elements.MoveNext();
                lastObject            = element;
                lastExpandedSkipToken = skipToken;
            }

            if (this.NeedNextPageLink(elements))
            {
                linksCollection.NextPageLink = this.GetNextLinkUri(lastObject, lastExpandedSkipToken, this.RequestDescription.ResultUri);
                yield break;
            }
        }
示例#2
0
        /// <summary>Writes multiple top-level elements, possibly none.</summary>
        /// <param name="expanded">Expanded properties for the result.</param>
        /// <param name="elements">Enumerator for elements to write.</param>
        protected override void WriteTopLevelElements(IExpandedResult expanded, QueryResultInfo elements)
        {
            Debug.Assert(elements != null, "elements != null");
            Debug.Assert(!this.RequestDescription.IsSingleResult, "!this.RequestDescription.SingleResult");

            string title;

            if (this.RequestDescription.TargetKind != RequestTargetKind.OpenProperty &&
                this.RequestDescription.TargetSource == RequestTargetSource.Property)
            {
                title = this.RequestDescription.Property.Name;
            }
            else
            {
                title = this.RequestDescription.ContainerName;
            }

            this.dataServicesODataWriter = this.CreateODataWriter(true /*forFeed*/);

            bool needPop = this.PushSegmentForRoot();

            this.WriteFeedElements(
                expanded,
                elements,
                this.RequestDescription.TargetResourceType.ElementType(),
                title,                                      // title
                () => new Uri(this.RequestDescription.LastSegmentInfo.Identifier, UriKind.Relative),
                () => this.RequestDescription.ResultUri,    // absoluteUri
                true);

            this.PopSegmentName(needPop);
        }
        private void SaveDynamicConnections(
            TemplateNodeInfo templateNode,
            MultyQueryResultInfo queriesResult
            )
        {
            foreach (TemplateNodeResultItem templateNodeResultItem in queriesResult.List)
            {
                TemplateNodeQueryInfo queryInfo         = templateNodeResultItem.TemplateNodeQuery;
                TemplateNodeInfo      templateNodeClone = templateNode;

                if (queryInfo.ConnectionsSelectId != null)
                {
                    QueryResultInfo queryResult = templateNodeResultItem.QueryResult;

                    foreach (InstanceInfo instanceInfo in templateNodeClone.ConnectionGroup.Connections)
                    {
                        Int64?destParentQueryId = this.CurrentStorage.QueryDirectory.GetQueryId(
                            templateNode,
                            queryInfo,
                            instanceInfo,
                            DateTime.Now,
                            false
                            );

                        foreach (KeyValuePair <InstanceInfo, QueryInstanceResultInfo> queryInstanceResultInfo in queryResult.InstancesResult)
                        {
                            InstanceInfo selectConnectionInstance = queryInstanceResultInfo.Key;

                            Int64?dynamicQueryId = this.CurrentStorage.QueryDirectory.GetQueryId(
                                templateNodeClone,
                                queryInfo,
                                selectConnectionInstance,
                                DateTime.Now,
                                false
                                );

                            if (destParentQueryId == null)
                            {
                                continue;
                            }

                            DynamicConnection dynamicConnection = new DynamicConnection(
                                selectConnectionInstance.Name,
                                selectConnectionInstance.Type.ToString(),
                                selectConnectionInstance.IsODBC,
                                dynamicQueryId
                                );

                            this.CurrentStorage.DynamicConnectionDirectory.UpdateConnection(
                                destParentQueryId.Value,
                                dynamicConnection
                                );
                        }
                    }
                }
            }
        }
示例#4
0
        private static QueryResultInfo GetQueryResultInfo_NetStandard(this IDataReader reader)
        {
#if NETSTANDARD2_0
            var colinfo = reader as IDbColumnSchemaGenerator;
            if (colinfo != null)
            {
                var res = new QueryResultInfo();
                foreach (var row in colinfo.GetColumnSchema())
                {
                    var col = new QueryResultColumnInfo();

                    int size = row.ColumnSize ?? 0;
                    col.Name       = row.ColumnName;
                    col.NotNull    = !(row.AllowDBNull ?? true);
                    col.DataType   = row.DataTypeName;
                    col.Size       = size;
                    col.CommonType = ReaderDataType(row);

                    col.BaseColumnName  = row.BaseColumnName;
                    col.BaseSchemaName  = row.BaseSchemaName;
                    col.BaseTableName   = row.BaseTableName;
                    col.BaseServerName  = row.BaseServerName;
                    col.BaseCatalogName = row.BaseCatalogName;
                    if (row.IsAutoIncrement ?? false)
                    {
                        col.CommonType.SetAutoincrement(true);
                        col.AutoIncrement = true;
                    }
                    if (row.IsKey ?? false)
                    {
                        col.IsKey = true;
                    }
                    if (row.IsHidden ?? false)
                    {
                        col.IsHidden = true;
                    }
                    if (row.IsReadOnly ?? false)
                    {
                        col.IsReadOnly = true;
                    }
                    if (row.IsAliased ?? false)
                    {
                        col.IsAliased = true;
                    }
                    res.Columns.Add(col);
                }
                return(res);
            }
            return(null);
#else
            retrun null;
#endif
        }
示例#5
0
        /// <summary>Writes multiple top-level elements, possibly none.</summary>
        /// <param name="expanded">Expanded results for elements.</param>
        /// <param name="elements">Enumerator for elements to write.</param>
        protected override void WriteTopLevelElements(IExpandedResult expanded, QueryResultInfo elements)
        {
            Debug.Assert(
                !this.RequestDescription.IsSingleResult,
                "!this.RequestDescription.IsSingleResult -- otherwise WriteTopLevelElement should have been called");

            if (this.RequestDescription.LinkUri)
            {
                bool needPop = this.PushSegmentForRoot();
                this.WriteLinkCollection(elements);
                this.PopSegmentName(needPop);
            }
            else
            {
                MetadataProviderEdmModel model     = this.Service.Provider.GetMetadataProviderEdmModel();
                OperationWrapper         operation = this.RequestDescription.LastSegmentInfo.Operation;

                IEdmOperation edmOperation = model.GetRelatedOperation(operation);
                Debug.Assert(edmOperation != null, "edmOperation != null");

                IEdmCollectionTypeReference collectionType = (IEdmCollectionTypeReference)edmOperation.ReturnType;
                bool isJsonLightResponse = ContentTypeUtil.IsResponseMediaTypeJsonLight(this.Service, /*isEntryOrFeed*/ false);
                this.collectionWriter = this.writer.CreateODataCollectionWriter(isJsonLightResponse ? null : collectionType.ElementType());

                ODataCollectionStart collectionStart = new ODataCollectionStart {
                    Name = this.ComputeContainerName()
                };
                collectionStart.SetSerializationInfo(new ODataCollectionStartSerializationInfo {
                    CollectionTypeName = collectionType.FullName()
                });

                this.collectionWriter.WriteStart(collectionStart);
                while (elements.HasMoved)
                {
                    object       element      = elements.Current;
                    ResourceType resourceType = element == null ?
                                                this.RequestDescription.TargetResourceType : WebUtil.GetResourceType(this.Provider, element);
                    if (resourceType == null)
                    {
                        throw new InvalidOperationException(Microsoft.OData.Service.Strings.Serializer_UnsupportedTopLevelType(element.GetType()));
                    }

                    this.collectionWriter.WriteItem(this.GetPropertyValue(XmlConstants.XmlCollectionItemElementName, resourceType, element, false /*openProperty*/).FromODataValue());
                    elements.MoveNext();
                }

                this.collectionWriter.WriteEnd();
                this.collectionWriter.Flush();
            }
        }
        internal void SaveMeta(
            TemplateNodeInfo templateNodeInfo,
            MultyQueryResultInfo results,
            long requestId,
            DateTime timestamp
            )
        {
            Debug.Assert(templateNodeInfo.IsInstance);

            Int64            sessionId = 1L;
            List <ITableRow> metaRows  = new List <ITableRow>();

            foreach (TemplateNodeResultItem tuple in results.List)
            {
                TemplateNodeQueryInfo templateNodeQuery = tuple.TemplateNodeQuery;
                QueryResultInfo       queryResult       = tuple.QueryResult;

                foreach (QueryInstanceResultInfo queryInstanceResult in queryResult.InstancesResult.Values)
                {
                    InstanceInfo instance = queryInstanceResult.Instance;

                    Int64?queryId = this.QueryDirectory.GetQueryId(
                        templateNodeInfo,
                        templateNodeQuery,
                        instance,
                        timestamp,
                        false);

                    Log.InfoFormat("Instance:'{0}';QueryId:'{1}'",
                                   instance,
                                   queryId
                                   );

                    ITableRow row = this.MetaResultTable.GetMetaRow(
                        requestId,
                        sessionId,
                        timestamp,
                        queryInstanceResult,
                        queryId,
                        null
                        );

                    metaRows.Add(row);
                }
            }

            this.MetaResultTable.ReplaceRows(metaRows);

            this.ResetRowCountCache(templateNodeInfo);
        }
示例#7
0
        /// <summary>
        /// Write out the uri for the given elements.
        /// </summary>
        /// <param name="elements">Elements whose uri need to be written out.</param>
        private void WriteLinkCollection(QueryResultInfo elements)
        {
            ODataEntityReferenceLinks linksCollection = new ODataEntityReferenceLinks();

            // write count?
            if (this.RequestDescription.CountOption == RequestQueryCountOption.CountQuery)
            {
                linksCollection.Count = this.RequestDescription.CountValue;
            }

            // assign the links collection
            linksCollection.Links = this.GetLinksCollection(elements, linksCollection);

            this.writer.WriteEntityReferenceLinks(linksCollection);
        }
 internal static QueryResultInfo GetSingleResultFromRequest(SegmentInfo segmentInfo)
 {
     Debug.Assert(segmentInfo != null && segmentInfo.RequestEnumerable != null, "segmentInfo != null && segmentInfo.RequestEnumerable != null");
     var queryResults = new QueryResultInfo(segmentInfo.RequestEnumerable);
     try
     {
         WebUtil.CheckResourceExists(queryResults.MoveNext(), segmentInfo.Identifier);
         WebUtil.CheckNullDirectReference(queryResults.Current, segmentInfo);
         return queryResults;
     }
     catch
     {
         // Dispose the Enumerator in case of error
         WebUtil.Dispose(queryResults);
         throw;
     }
 }
示例#9
0
 private static QueryResultInfo GetQueryResultInfo_OnlyColumnNames(this IDataReader reader)
 {
     try
     {
         var res = new QueryResultInfo();
         for (int i = 0; i < reader.FieldCount; i++)
         {
             var column = new QueryResultColumnInfo();
             column.Name = reader.GetName(i);
             res.Columns.Add(column);
         }
         return(res);
     }
     catch
     {
         return(null);
     }
 }
        internal static QueryResultInfo GetSingleResultFromRequest(SegmentInfo segmentInfo)
        {
            Debug.Assert(segmentInfo != null && segmentInfo.RequestEnumerable != null, "segmentInfo != null && segmentInfo.RequestEnumerable != null");
            var queryResults = new QueryResultInfo(segmentInfo.RequestEnumerable);

            try
            {
                WebUtil.CheckResourceExists(queryResults.MoveNext(), segmentInfo.Identifier);
                WebUtil.CheckNullDirectReference(queryResults.Current, segmentInfo);
                return(queryResults);
            }
            catch
            {
                // Dispose the Enumerator in case of error
                WebUtil.Dispose(queryResults);
                throw;
            }
        }
示例#11
0
        /// <summary>
        /// Append errors to log
        /// </summary>
        /// <param name="queryResult">from query result</param>
        public void AppendErrorLog(QueryResultInfo queryResult)
        {
            foreach (KeyValuePair <InstanceInfo, QueryInstanceResultInfo> instancePair in queryResult.InstancesResult)
            {
                var instance = instancePair.Value;

                if (instance.ErrorInfo != null)
                {
                    this._errorItems.Add(new ErrorLogItem(instance.ErrorInfo.DateTime, instance.Instance, null, instance.ErrorInfo.Exception));
                }
                else
                {
                    foreach (KeyValuePair <string, QueryDatabaseResultInfo> databasePair in instance.DatabasesResult)
                    {
                        var database = databasePair.Value;

                        if (database.ErrorInfo != null)
                        {
                            this._errorItems.Add(new ErrorLogItem(database.ErrorInfo.DateTime, instance.Instance, database.QueryItem, database.ErrorInfo.Exception));
                        }
                    }
                }
            }
        }
示例#12
0
        /// <summary>
        /// Return the collection of links as ODataEntityReferenceLink instances
        /// </summary>
        /// <param name="elements">Elements whose uri need to be written out.</param>
        /// <param name="linksCollection">LinkCollection instance which represents the collection getting written out.</param>
        /// <returns>Return the collection of links as ODataEntityReferenceLink instances.</returns>
        private IEnumerable<ODataEntityReferenceLink> GetLinksCollection(QueryResultInfo elements, ODataEntityReferenceLinks linksCollection)
        {
            object lastObject = null;
            IExpandedResult lastExpandedSkipToken = null;
            while (elements.HasMoved)
            {
                object element = elements.Current;
                IExpandedResult skipToken = null;
                if (element != null)
                {
                    IExpandedResult expanded = element as IExpandedResult;
                    if (expanded != null)
                    {
                        element = GetExpandedElement(expanded);
                        skipToken = this.GetSkipToken(expanded);
                    }
                }

                this.IncrementSegmentResultCount();
                yield return new ODataEntityReferenceLink { Url = this.GetEntityEditLink(element) };
                elements.MoveNext();
                lastObject = element;
                lastExpandedSkipToken = skipToken;
            }

            if (this.NeedNextPageLink(elements))
            {
                linksCollection.NextPageLink = this.GetNextLinkUri(lastObject, lastExpandedSkipToken, this.RequestDescription.ResultUri);
                yield break;
            }
        }
示例#13
0
        public static QueryResultInfo SchemaTableToInfo(DataTable schemaTable)
        {
            var res = new QueryResultInfo();

            foreach (DataRow row in schemaTable.Rows.SortedByKey <DataRow, int>(row => Int32.Parse(row["ColumnOrdinal"].ToString())))
            {
                var col  = new QueryResultColumnInfo();
                int size = row.SafeString("ColumnSize").SafeIntParse();
                col.Name = row.SafeString("ColumnName");
                if (row["AllowDBNull"] is bool notNull)
                {
                    col.NotNull = !notNull;
                }

                int dataTypeNameIndex = row.Table.Columns.GetOrdinal("DataTypeName");
                int dataTypeIndex     = row.Table.Columns.GetOrdinal("DataType");
                if (dataTypeNameIndex >= 0)
                {
                    col.DataType = row[dataTypeNameIndex].SafeToString();
                }
                else if (dataTypeIndex >= 0)
                {
                    col.DataType = (row[dataTypeIndex] as Type)?.Name ?? "String";
                }
                else
                {
                    col.DataType = "String";
                }

                col.Size       = size;
                col.CommonType = ReaderDataType(row);

                col.BaseColumnName  = row.SafeString("BaseColumnName");
                col.BaseSchemaName  = row.SafeString("BaseSchemaName");
                col.BaseTableName   = row.SafeString("BaseTableName");
                col.BaseServerName  = row.SafeString("BaseServerName");
                col.BaseCatalogName = row.SafeString("BaseCatalogName");
                if (row.SafeBool("IsAutoIncrement", false))
                {
                    col.CommonType.SetAutoincrement(true);
                    col.AutoIncrement = true;
                }
                if (row.SafeBool("IsKey", false))
                {
                    col.IsKey = true;
                }
                if (row.SafeBool("IsHidden", false))
                {
                    col.IsHidden = true;
                }
                if (row.SafeBool("IsReadOnly", false))
                {
                    col.IsReadOnly = true;
                }
                if (row.SafeBool("IsAliased", false))
                {
                    col.IsAliased = true;
                }
                res.Columns.Add(col);
            }
            return(res);
        }
示例#14
0
        /// <summary>Writes multiple top-level elements, possibly none.</summary>
        /// <param name="expanded">Expanded properties for the result.</param>
        /// <param name="elements">Enumerator for elements to write.</param>
        protected override void WriteTopLevelElements(IExpandedResult expanded, QueryResultInfo elements)
        {
            Debug.Assert(elements != null, "elements != null");
            Debug.Assert(!this.RequestDescription.IsSingleResult, "!this.RequestDescription.SingleResult");

            string title;
            if (this.RequestDescription.TargetKind != RequestTargetKind.OpenProperty &&
                this.RequestDescription.TargetSource == RequestTargetSource.Property)
            {
                title = this.RequestDescription.Property.Name;
            }
            else
            {
                title = this.RequestDescription.ContainerName;
            }

            this.dataServicesODataWriter = this.CreateODataWriter(true /*forFeed*/);

            bool needPop = this.PushSegmentForRoot();
            this.WriteFeedElements(
                expanded,
                elements,
                this.RequestDescription.TargetResourceType.ElementType(),
                title,                                      // title
                () => new Uri(this.RequestDescription.LastSegmentInfo.Identifier, UriKind.Relative),
                () => this.RequestDescription.ResultUri,    // absoluteUri
                true);

            this.PopSegmentName(needPop);
        }
        public XmlDocument Transform(QueryResultDataSource dataSource)
        {
            GroupDefinition      database      = dataSource.NodeDefinition.Group;
            MultyQueryResultInfo queriesResult = dataSource.QueriesResult;
            MsSqlAuditorModel    model         = dataSource.Model;

            if (queriesResult == null)
            {
                return(null);
            }

            try
            {
                DateTime    timestamp = queriesResult.Timestamp;
                XmlDocument xml       = new XmlDocument();

                xml.AppendChild(xml.CreateXmlDeclaration("1.0", "UTF-8", String.Empty));

                XmlElement rootNode = xml.CreateElement(Consts.ResultsTag);
                rootNode.SetAttribute(TimestampAttributeName, timestamp.ToInternetString());
                xml.AppendChild(rootNode);

                foreach (TemplateNodeResultItem tuple in queriesResult.List)
                {
                    TemplateNodeQueryInfo templateNodeQueryInfo = tuple.TemplateNodeQuery;
                    QueryResultInfo       queryResult           = tuple.QueryResult;

                    foreach (
                        KeyValuePair <InstanceInfo, QueryInstanceResultInfo> instancePair in queryResult.InstancesResult)
                    {
                        InstanceInfo instance = instancePair.Key;

                        QueryInstanceResultInfo queryInstanceResult = instancePair.Value;

                        if (queryInstanceResult.ErrorInfo == null)
                        {
                            try
                            {
                                QueryDatabaseResultInfo databaseResult = queryInstanceResult.DatabasesResult[database.Name];
                                int rowCount = 0;

                                if (databaseResult != null)
                                {
                                    rowCount = databaseResult.DataTables != null
                                                                                ? databaseResult.DataTables.Where(x => x != null).Select(x => x.Rows).Sum(x => x.Count)
                                                                                : 0;
                                }

                                GenerateResultDefinition(
                                    rootNode,
                                    templateNodeQueryInfo,
                                    databaseResult.ErrorInfo,
                                    instance,
                                    rowCount,
                                    (databaseResult.DataTables != null ? databaseResult.DataTables.Length : 0)
                                    );
                            }
                            catch (Exception ex)
                            {
                                log.Error("Error in 'Extracts data from queries and saves it to Xml-files'", ex);
                            }
                        }
                        else
                        {
                            GenerateResultDefinition(
                                rootNode,
                                templateNodeQueryInfo,
                                queryInstanceResult.ErrorInfo,
                                instance,
                                0,
                                0
                                );
                        }
                    }
                }

                foreach (TemplateNodeResultItem tuple in queriesResult.List)
                {
                    TemplateNodeQueryInfo templateNodeQueryInfo = tuple.TemplateNodeQuery;

                    if (templateNodeQueryInfo.GetType() != typeof(TemplateNodeSqlGuardQueryInfo))
                    {
                        model.GetQueryByTemplateNodeQueryInfo(templateNodeQueryInfo);
                    }

                    QueryResultInfo queryResult = tuple.QueryResult;

                    foreach (
                        KeyValuePair <InstanceInfo, QueryInstanceResultInfo> instancePair in queryResult.InstancesResult)
                    {
                        InstanceInfo            instance            = instancePair.Key;
                        QueryInstanceResultInfo queryInstanceResult = instancePair.Value;

                        if (queryInstanceResult.ErrorInfo == null)
                        {
                            foreach (KeyValuePair <string, QueryDatabaseResultInfo> namedResult in queryInstanceResult.DatabasesResult)
                            {
                                if (namedResult.Key == database.Name)
                                {
                                    XmlNode parent = rootNode.ChildNodes.OfType <XmlNode>().FirstOrDefault(
                                        x =>
                                        (
                                            x.Attributes["instance"] != null &&
                                            x.Attributes["instance"].Value == instance.Name
                                        )
                                        &&
                                        (
                                            x.Attributes["name"] != null &&
                                            x.Attributes["name"].Value == templateNodeQueryInfo.QueryName
                                        )
                                        &&
                                        (
                                            x.Attributes["hierarchy"] != null &&
                                            x.Attributes["hierarchy"].Value == (templateNodeQueryInfo.ResultHierarchy ?? string.Empty)
                                        )
                                        );

                                    QueryDatabaseResultInfo databaseResult = namedResult.Value;

                                    if (databaseResult.DataTables != null)
                                    {
                                        Int64 recordSet = 1L;

                                        foreach (DataTable curTable in databaseResult.DataTables)
                                        {
                                            if (parent != null)
                                            {
                                                parent.InnerXml = parent.InnerXml +
                                                                  ProcessDataTableAsStringXml(curTable, recordSet);
                                            }

                                            recordSet++;
                                        }
                                    }

                                    if (databaseResult.QueryItem.ParentQuery.Scope == QueryScope.Database)
                                    {
                                        if (!string.IsNullOrEmpty(databaseResult.Database))
                                        {
                                            XmlAttribute attr = xml.CreateAttribute("database");
                                            attr.Value = databaseResult.Database;
                                            parent.Attributes.Append(attr);
                                        }

                                        if (!string.IsNullOrEmpty(databaseResult.DatabaseId))
                                        {
                                            XmlAttribute attr = xml.CreateAttribute("databaseId");
                                            attr.Value = databaseResult.DatabaseId;
                                            parent.Attributes.Append(attr);
                                        }
                                    }
                                    else if (databaseResult.QueryItem.ParentQuery.Scope == QueryScope.InstanceGroup)
                                    {
                                        if (!string.IsNullOrEmpty(databaseResult.Database))
                                        {
                                            XmlAttribute attr = xml.CreateAttribute("InstanceGroupName");
                                            attr.Value = databaseResult.Database;
                                            parent.Attributes.Append(attr);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                return(xml);
            }
            catch (Exception ex)
            {
                log.Error("Error in 'Extracts data from queries and saves it to Xml-files'", ex);
            }

            return(null);
        }
示例#16
0
        private TemplateNodeResultItem ReadTemplateNodeResult(TemplateNodeQueryInfo templateNodeQueryInfo, MultyQueryResultInfo result)
        {
            var queryResult          = new QueryResultInfo();
            List <QueryInfo> queries = MsSqlAuditor.GetQueryByTemplateNodeQueryInfo(templateNodeQueryInfo);

            // looking for user settings for parameter values
            templateNodeQueryInfo.ReadParametersFrom(Settings);

            string connectionsSelectId = templateNodeQueryInfo.ConnectionsSelectId;

            if (connectionsSelectId != null)
            {
                foreach (InstanceInfo instance in this._instances)
                {
                    Int64?queryId = Storage.QueryDirectory.GetQueryId(
                        templateNodeQueryInfo.TemplateNode,
                        templateNodeQueryInfo,
                        instance,
                        DateTime.Now,
                        false
                        );

                    if (queryId.HasValue)
                    {
                        List <DynamicConnection> connections = new List <DynamicConnection>(
                            Storage.DynamicConnectionDirectory.ReadConnections(queryId.Value)
                            );

                        foreach (DynamicConnection connection in connections)
                        {
                            if (!connection.QueryId.HasValue)
                            {
                                continue;
                            }

                            Int64       dynamicQueryId = connection.QueryId.Value;
                            QuerySource sourceType;

                            if (!Enum.TryParse(connection.Type, true, out sourceType))
                            {
                                _log.ErrorFormat(
                                    @"Unknown ConnectionType:'{0}'",
                                    connection.Type ?? "<Null>"
                                    );

                                sourceType = QuerySource.MSSQL;
                            }

                            InstanceInfo selectConnectionInstance = InstanceInfoResolver.ResolveDynamicInstance(
                                connection.Name,
                                sourceType,
                                connection.IsOdbc
                                );

                            selectConnectionInstance.ConnectionGroup = instance.ConnectionGroup;

                            selectConnectionInstance.LoadServerProperties(Storage);

                            QueryInstanceResultInfo instanceResult = GetInstanceResult(
                                result,
                                selectConnectionInstance,
                                dynamicQueryId,
                                templateNodeQueryInfo,
                                queries
                                );

                            if (instanceResult != null)
                            {
                                queryResult.AddInstanceResult(instanceResult);
                            }
                        }
                    }
                }
            }
            else
            {
                foreach (InstanceInfo instance in this._instances)
                {
                    Int64?queryId = Storage.QueryDirectory.GetQueryId(
                        base.TemplateNode,
                        templateNodeQueryInfo,
                        instance,
                        new DateTime(),
                        true
                        );

                    if (queryId != null)
                    {
                        QueryInstanceResultInfo instanceResult = GetInstanceResult(
                            result,
                            instance,
                            queryId.Value,
                            templateNodeQueryInfo,
                            queries
                            );

                        if (instanceResult != null)
                        {
                            queryResult.AddInstanceResult(instanceResult);
                        }
                    }
                }
            }

            Tuple <DateTime?, DateTime?> dateTimes =
                Storage.NodeInstances.GetTreeNodeLastUpdateAndDuration(base.TemplateNode);

            result.NodeLastUpdated        = dateTimes.Item1;
            result.NodeLastUpdateDuration = dateTimes.Item2;

            return(new TemplateNodeResultItem(templateNodeQueryInfo, queryResult));
        }
示例#17
0
        /// <summary>
        /// Writes the feed element for the atom payload.
        /// </summary>
        /// <param name="expanded">Expanded properties for the result.</param>
        /// <param name="elements">Collection of entries in the feed element.</param>
        /// <param name="expectedType">ExpectedType of the elements in the collection.</param>
        /// <param name="title">Title of the feed element.</param>
        /// <param name="getRelativeUri">Callback to get the relative uri of the feed.</param>
        /// <param name="getAbsoluteUri">Callback to get the absolute uri of the feed.</param>
        /// <param name="topLevel">True if the feed is the top level feed, otherwise false for the inner expanded feed.</param>
        private void WriteFeedElements(
            IExpandedResult expanded,
            QueryResultInfo elements,
            ResourceType expectedType,
            string title,
            Func<Uri> getRelativeUri,
            Func<Uri> getAbsoluteUri,
            bool topLevel)
        {
            Debug.Assert(elements != null, "elements != null");
            Debug.Assert(expectedType != null && expectedType.ResourceTypeKind == ResourceTypeKind.EntityType, "expectedType != null && expectedType.ResourceTypeKind == ResourceTypeKind.EntityType");
            Debug.Assert(!string.IsNullOrEmpty(title), "!string.IsNullOrEmpty(title)");

            ODataFeed feed = new ODataFeed();
            feed.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo { NavigationSourceName = this.CurrentContainer.Name, NavigationSourceEntityTypeName = this.CurrentContainer.ResourceType.FullName, ExpectedTypeName = expectedType.FullName });

            // Write the other elements for the feed
            this.PayloadMetadataPropertyManager.SetId(feed, () => getAbsoluteUri());

#pragma warning disable 618
            if (this.contentFormat == ODataFormat.Atom)
#pragma warning restore 618
            {
                // Create the atom feed metadata and set the self link and title value.
                AtomFeedMetadata feedMetadata = new AtomFeedMetadata();
                feed.SetAnnotation(feedMetadata);
                feedMetadata.Title = new AtomTextConstruct { Text = title };
                feedMetadata.SelfLink = new AtomLinkMetadata { Href = getRelativeUri(), Title = title };
            }

            // support for $count
            // in ATOM we write it at the beginning (we always have)
            //   in JSON for backward compatiblity reasons we write it at the end, so we must not fill it here.
            if (topLevel && this.RequestDescription.CountOption == RequestQueryCountOption.CountQuery)
            {
                feed.Count = this.RequestDescription.CountValue;
            }

            var feedArgs = elements.GetDataServiceODataWriterFeedArgs(feed, this.Service.OperationContext);
            this.dataServicesODataWriter.WriteStart(feedArgs);
            object lastObject = null;
            IExpandedResult lastExpandedSkipToken = null;
            while (elements.HasMoved)
            {
                object o = elements.Current;
                IExpandedResult skipToken = this.GetSkipToken(expanded);

                if (o != null)
                {
                    IExpandedResult expandedO = o as IExpandedResult;
                    if (expandedO != null)
                    {
                        expanded = expandedO;
                        o = GetExpandedElement(expanded);
                        skipToken = this.GetSkipToken(expanded);
                    }

                    this.WriteEntry(expanded, o, true /*resourceInstanceInFeed*/, expectedType);
                }

                elements.MoveNext();
                lastObject = o;
                lastExpandedSkipToken = skipToken;
            }

            // After looping through the objects in the sequence, decide if we need to write the next
            // page link and if yes, write it by invoking the delegate
            if (this.NeedNextPageLink(elements))
            {
                this.PayloadMetadataPropertyManager.SetNextPageLink(
                    feed,
                    this.AbsoluteServiceUri,
                    this.GetNextLinkUri(lastObject, lastExpandedSkipToken, getAbsoluteUri()));
            }

            this.dataServicesODataWriter.WriteEnd(feedArgs);
#if ASTORIA_FF_CALLBACKS
            this.Service.InternalOnWriteFeed(feed);
#endif
        }
 public override void VisitBefore(QueryResultInfo resultInfo)
 {
 }
示例#19
0
        /// <summary>
        /// Writes the feed element for the atom payload.
        /// </summary>
        /// <param name="expanded">Expanded properties for the result.</param>
        /// <param name="elements">Collection of entries in the feed element.</param>
        /// <param name="expectedType">ExpectedType of the elements in the collection.</param>
        /// <param name="title">Title of the feed element.</param>
        /// <param name="getRelativeUri">Callback to get the relative uri of the feed.</param>
        /// <param name="getAbsoluteUri">Callback to get the absolute uri of the feed.</param>
        /// <param name="topLevel">True if the feed is the top level feed, otherwise false for the inner expanded feed.</param>
        private void WriteFeedElements(
            IExpandedResult expanded,
            QueryResultInfo elements,
            ResourceType expectedType,
            string title,
            Func <Uri> getRelativeUri,
            Func <Uri> getAbsoluteUri,
            bool topLevel)
        {
            Debug.Assert(elements != null, "elements != null");
            Debug.Assert(expectedType != null && expectedType.ResourceTypeKind == ResourceTypeKind.EntityType, "expectedType != null && expectedType.ResourceTypeKind == ResourceTypeKind.EntityType");
            Debug.Assert(!string.IsNullOrEmpty(title), "!string.IsNullOrEmpty(title)");

            ODataFeed feed = new ODataFeed();

            feed.SetSerializationInfo(new ODataFeedAndEntrySerializationInfo {
                NavigationSourceName = this.CurrentContainer.Name, NavigationSourceEntityTypeName = this.CurrentContainer.ResourceType.FullName, ExpectedTypeName = expectedType.FullName
            });

            // Write the other elements for the feed
            this.PayloadMetadataPropertyManager.SetId(feed, () => getAbsoluteUri());

#pragma warning disable 618
            if (this.contentFormat == ODataFormat.Atom)
#pragma warning restore 618
            {
                // Create the atom feed metadata and set the self link and title value.
                AtomFeedMetadata feedMetadata = new AtomFeedMetadata();
                feed.SetAnnotation(feedMetadata);
                feedMetadata.Title = new AtomTextConstruct {
                    Text = title
                };
                feedMetadata.SelfLink = new AtomLinkMetadata {
                    Href = getRelativeUri(), Title = title
                };
            }

            // support for $count
            // in ATOM we write it at the beginning (we always have)
            //   in JSON for backward compatiblity reasons we write it at the end, so we must not fill it here.
            if (topLevel && this.RequestDescription.CountOption == RequestQueryCountOption.CountQuery)
            {
                feed.Count = this.RequestDescription.CountValue;
            }

            var feedArgs = elements.GetDataServiceODataWriterFeedArgs(feed, this.Service.OperationContext);
            this.dataServicesODataWriter.WriteStart(feedArgs);
            object          lastObject            = null;
            IExpandedResult lastExpandedSkipToken = null;
            while (elements.HasMoved)
            {
                object          o         = elements.Current;
                IExpandedResult skipToken = this.GetSkipToken(expanded);

                if (o != null)
                {
                    IExpandedResult expandedO = o as IExpandedResult;
                    if (expandedO != null)
                    {
                        expanded  = expandedO;
                        o         = GetExpandedElement(expanded);
                        skipToken = this.GetSkipToken(expanded);
                    }

                    this.WriteEntry(expanded, o, true /*resourceInstanceInFeed*/, expectedType);
                }

                elements.MoveNext();
                lastObject            = o;
                lastExpandedSkipToken = skipToken;
            }

            // After looping through the objects in the sequence, decide if we need to write the next
            // page link and if yes, write it by invoking the delegate
            if (this.NeedNextPageLink(elements))
            {
                this.PayloadMetadataPropertyManager.SetNextPageLink(
                    feed,
                    this.AbsoluteServiceUri,
                    this.GetNextLinkUri(lastObject, lastExpandedSkipToken, getAbsoluteUri()));
            }

            this.dataServicesODataWriter.WriteEnd(feedArgs);
#if ASTORIA_FF_CALLBACKS
            this.Service.InternalOnWriteFeed(feed);
#endif
        }
示例#20
0
        private void ProcessCodeGuardQuery(
            MultyQueryResultInfo result,
            TemplateNodeSqlGuardQueryInfo guardQueryInfo)
        {
            var queryResultInfo       = result.List.First(item => item.TemplateNodeQuery.Id == guardQueryInfo.SqlQueryId);
            var templateNodeQueryInfo = queryResultInfo.TemplateNodeQuery;
            var userParams            = new List <ParameterValue>();

            if (base.Settings != null)
            {
                var querySettings = base.Settings.Connection.Activity.Parameters
                                    .Where(i => i.Key == guardQueryInfo.IdsHierarchy && i.Value != null);

                foreach (var info in querySettings)
                {
                    switch (info.Type)
                    {
                    case ParameterInfoType.Attribute:
                        guardQueryInfo.GetType().GetProperty("User" + info.Parameter)
                        .SetValue(guardQueryInfo, info.Value, null);
                        break;

                    case ParameterInfoType.Parameter:
                        var parameter =
                            templateNodeQueryInfo.ParameterValues.FirstOrDefault(p => p.Name == info.Parameter);
                        if (parameter != null)
                        {
                            parameter.UserValue = info.Value;
                        }
                        break;

                    case ParameterInfoType.EditableParameter:
                        var editparameter = new ParameterValue
                        {
                            Name        = info.Parameter,
                            StringValue = info.Default,
                            UserValue   = info.Value
                        };
                        userParams.Add(editparameter);
                        break;
                    }
                }
            }

            var guardQueryResult = new QueryResultInfo();

            foreach (var instanceResult in queryResultInfo.QueryResult.InstancesResult)
            {
                var instance   = instanceResult.Key;
                var queryTable = instanceResult.Value.DatabasesResult.First().Value.DataTables.First();

                if (!queryTable.Columns.Contains(guardQueryInfo.QueryCodeColumn))
                {
                    continue;
                }

                //var meta = ReadMeta(connectionGroup, templateNode, instance, database, templateNodeQueryInfo).FirstOrDefault();
                var meta = Storage.ReadLastMeta(
                    base.TemplateNode,
                    instance,
                    templateNodeQueryInfo
                    );

                if (meta == null)
                {
                    continue;
                }

                QueryInstanceResultInfo guardInstanceResult;
                var timestamp = (DateTime)meta.Values[TableDefinition.DateCreated];

                result.RefreshTimestamp(timestamp);

                if (!string.IsNullOrEmpty(meta.Values[MetaResultTable.ErrorMessageFieldName].ToString()))
                {
                    guardInstanceResult = new QueryInstanceResultInfo(
                        new ErrorInfo(
                            meta.Values[MetaResultTable.ErrorIdFieldName].ToString(),
                            meta.Values[MetaResultTable.ErrorCodeFieldName].ToString(),
                            meta.Values[MetaResultTable.ErrorMessageFieldName].ToString(),
                            timestamp
                            ),
                        instance
                        );
                }
                else
                {
                    guardInstanceResult = new QueryInstanceResultInfo(instance);
                }

                var dataTables = Storage.ReadSqlCodeGuardResult(guardQueryInfo, queryTable, userParams);

                QueryItemInfo queryItemInfo = new QueryItemInfo
                {
                    ParentQuery = new QueryInfo {
                        Name = guardQueryInfo.QueryName
                    }
                };

                QueryDatabaseResultInfo databaseResult = new QueryDatabaseResultInfo(
                    dataTables,
                    queryItemInfo,
                    base.GroupDefinition.Name,
                    base.GroupDefinition.Id
                    );

                guardInstanceResult.AddDatabaseResult(databaseResult);
                guardQueryResult.AddInstanceResult(guardInstanceResult);
            }

            var templateNodeResultItem = new TemplateNodeResultItem(guardQueryInfo, guardQueryResult);

            result.Add(templateNodeResultItem);
        }
示例#21
0
        private void WriteNavigationProperties(IExpandedResult expanded, EntityToSerialize entityToSerialize, bool resourceInstanceInFeed, IEnumerable<ProjectionNode> projectionNodesForCurrentResourceType)
        {
            Debug.Assert(entityToSerialize != null, "entityToSerialize != null");
            Debug.Assert(
                projectionNodesForCurrentResourceType == null ||
                projectionNodesForCurrentResourceType.All(projectionNode => projectionNode.TargetResourceType.IsAssignableFrom(entityToSerialize.ResourceType)),
                "The projection nodes must be filtered to the current resource type only.");

            IEnumerable<ResourceProperty> navProperties =
                projectionNodesForCurrentResourceType == null
                ? this.Provider.GetResourceSerializableProperties(this.CurrentContainer, entityToSerialize.ResourceType).Where(p => p.TypeKind == ResourceTypeKind.EntityType)
                : projectionNodesForCurrentResourceType.Where(p => p.Property != null && p.Property.TypeKind == ResourceTypeKind.EntityType).Select(p1 => p1.Property);

            foreach (ResourceProperty property in navProperties)
            {
                ResourcePropertyInfo navProperty = this.GetNavigationPropertyInfo(expanded, entityToSerialize.Entity, entityToSerialize.ResourceType, property);
                ODataNavigationLink navLink = this.GetNavigationLink(entityToSerialize, navProperty.Property);

                // WCF Data Services show performance degradation with JsonLight when entities have > 25 Navgations on writing entries
                // DEVNOTE: for performance reasons, if the link has no content due to the metadata level, and is not expanded
                // then don't tell ODataLib about it at all.
                if (navLink.Url == null && navLink.AssociationLinkUrl == null && !navProperty.Expand)
                {
                    continue;
                }

                var linkArgs = new DataServiceODataWriterNavigationLinkArgs(navLink, this.Service.OperationContext);
                this.dataServicesODataWriter.WriteStart(linkArgs);

                if (navProperty.Expand)
                {
                    object navPropertyValue = navProperty.Value;
                    IExpandedResult navPropertyExpandedResult = navPropertyValue as IExpandedResult;
                    object expandedPropertyValue =
                                navPropertyExpandedResult != null ?
                                GetExpandedElement(navPropertyExpandedResult) :
                                navPropertyValue;

                    bool needPop = this.PushSegmentForProperty(navProperty.Property, entityToSerialize.ResourceType, navProperty.ExpandedNode);

                    // if this.CurrentContainer is null, the target set of the navigation property is hidden.
                    if (this.CurrentContainer != null)
                    {
                        if (navProperty.Property.Kind == ResourcePropertyKind.ResourceSetReference)
                        {
                            IEnumerable enumerable;
                            bool collection = WebUtil.IsElementIEnumerable(expandedPropertyValue, out enumerable);
                            Debug.Assert(collection, "metadata loading must have ensured that navigation set properties must implement IEnumerable");

                            QueryResultInfo queryResults = new QueryResultInfo(enumerable);
                            try
                            {
                                queryResults.MoveNext();
                                Func<Uri> getNavPropertyRelativeUri = () => RequestUriProcessor.AppendUnescapedSegment(entityToSerialize.SerializedKey.RelativeEditLink, navLink.Name);
                                Func<Uri> getNavPropertyAbsoluteUri = () => RequestUriProcessor.AppendUnescapedSegment(entityToSerialize.SerializedKey.AbsoluteEditLink, navLink.Name);
                                this.WriteFeedElements(navPropertyExpandedResult, queryResults, navProperty.Property.ResourceType, navLink.Name, getNavPropertyRelativeUri, getNavPropertyAbsoluteUri, false);
                            }
                            finally
                            {
                                // After the navigation property is completely serialized, dispose the property value.
                                WebUtil.Dispose(queryResults);
                            }
                        }
                        else if (WebUtil.IsNullValue(expandedPropertyValue))
                        {
                            // Write a null reference navigation property
                            var entryArgs = new DataServiceODataWriterEntryArgs(null, null, this.Service.OperationContext);
                            this.dataServicesODataWriter.WriteStart(entryArgs);
                            this.dataServicesODataWriter.WriteEnd(entryArgs);
                        }
                        else
                        {
                            this.WriteEntry(navPropertyExpandedResult, expandedPropertyValue, resourceInstanceInFeed, navProperty.Property.ResourceType);
                        }
                    }

                    this.PopSegmentName(needPop);
                }

                this.dataServicesODataWriter.WriteEnd(linkArgs); // end of navigation property
            }
        }
示例#22
0
        /// <summary>Writes multiple top-level elements, possibly none.</summary>
        /// <param name="expanded">Expanded results for elements.</param>
        /// <param name="elements">Enumerator for elements to write.</param>
        protected override void WriteTopLevelElements(IExpandedResult expanded, QueryResultInfo elements)
        {
            Debug.Assert(
                !this.RequestDescription.IsSingleResult,
                "!this.RequestDescription.IsSingleResult -- otherwise WriteTopLevelElement should have been called");

            if (this.RequestDescription.LinkUri)
            {
                bool needPop = this.PushSegmentForRoot();
                this.WriteLinkCollection(elements);
                this.PopSegmentName(needPop);
            }
            else
            {
                MetadataProviderEdmModel model = this.Service.Provider.GetMetadataProviderEdmModel();
                OperationWrapper operation = this.RequestDescription.LastSegmentInfo.Operation;
                
                IEdmOperation edmOperation = model.GetRelatedOperation(operation);
                Debug.Assert(edmOperation != null, "edmOperation != null");

                IEdmCollectionTypeReference collectionType = (IEdmCollectionTypeReference)edmOperation.ReturnType;
                bool isJsonLightResponse = ContentTypeUtil.IsResponseMediaTypeJsonLight(this.Service, /*isEntryOrFeed*/ false);
                this.collectionWriter = this.writer.CreateODataCollectionWriter(isJsonLightResponse ? null : collectionType.ElementType());

                ODataCollectionStart collectionStart = new ODataCollectionStart { Name = this.ComputeContainerName() };
                collectionStart.SetSerializationInfo(new ODataCollectionStartSerializationInfo { CollectionTypeName = collectionType.FullName() });

                this.collectionWriter.WriteStart(collectionStart);
                while (elements.HasMoved)
                {
                    object element = elements.Current;
                    ResourceType resourceType = element == null ?
                        this.RequestDescription.TargetResourceType : WebUtil.GetResourceType(this.Provider, element);
                    if (resourceType == null)
                    {
                        throw new InvalidOperationException(Microsoft.OData.Service.Strings.Serializer_UnsupportedTopLevelType(element.GetType()));
                    }

                    this.collectionWriter.WriteItem(this.GetPropertyValue(XmlConstants.XmlCollectionItemElementName, resourceType, element, false /*openProperty*/).FromODataValue());
                    elements.MoveNext();
                }

                this.collectionWriter.WriteEnd();
                this.collectionWriter.Flush();
            }
        }
        public void SaveRequestedData(
            TemplateNodeInfo templateNodeInfo,
            MultyQueryResultInfo results
            )
        {
            Debug.Assert(templateNodeInfo.IsInstance);

            long             requestId = this.CurrentStorage.MetaResultTable.GetMaxRequestId() + 1L;
            DateTime         timestamp = DateTime.Now;
            const long       sessionId = 1L;
            List <ITableRow> metaRows  = new List <ITableRow>();

            foreach (TemplateNodeResultItem nodeResult in results.List)
            {
                TemplateNodeQueryInfo templateNodeQuery = nodeResult.TemplateNodeQuery;
                QueryResultInfo       queryResult       = nodeResult.QueryResult;

                foreach (KeyValuePair <InstanceInfo, QueryInstanceResultInfo> instancePair in queryResult.InstancesResult)
                {
                    long                    totalRowsSaved      = 0L;
                    InstanceInfo            instance            = instancePair.Key;
                    QueryInstanceResultInfo queryInstanceResult = instancePair.Value;

                    Int64?queryId = CurrentStorage.QueryDirectory.GetQueryId(
                        templateNodeInfo,
                        templateNodeQuery,
                        instance,
                        timestamp,
                        false
                        );

                    Log.InfoFormat("Instance:'{0}';QueryId:'{1}'",
                                   instance,
                                   queryId
                                   );

                    if (queryInstanceResult.ErrorInfo == null)
                    {
                        IEnumerable <QueryDatabaseResultInfo> notEmptyResults = queryInstanceResult.DatabasesResult.Values
                                                                                .Where(d => d != null && d.DataTables != null);

                        foreach (QueryDatabaseResultInfo databaseResultInfo in notEmptyResults)
                        {
                            totalRowsSaved += SaveDatabaseResult(
                                templateNodeQuery,
                                instance,
                                databaseResultInfo,
                                queryId
                                );
                        }
                    }

                    ITableRow metaRow = this.CurrentStorage.MetaResultTable.GetMetaRow(
                        requestId,
                        sessionId,
                        timestamp,
                        queryInstanceResult,
                        queryId,
                        totalRowsSaved
                        );

                    metaRows.Add(metaRow);
                }
            }

            this.CurrentStorage.MetaResultTable.ReplaceRows(metaRows);
            this.CurrentStorage.ResetRowCountCache(templateNodeInfo);
        }
示例#24
0
        private void WriteNavigationProperties(IExpandedResult expanded, EntityToSerialize entityToSerialize, bool resourceInstanceInFeed, IEnumerable <ProjectionNode> projectionNodesForCurrentResourceType)
        {
            Debug.Assert(entityToSerialize != null, "entityToSerialize != null");
            Debug.Assert(
                projectionNodesForCurrentResourceType == null ||
                projectionNodesForCurrentResourceType.All(projectionNode => projectionNode.TargetResourceType.IsAssignableFrom(entityToSerialize.ResourceType)),
                "The projection nodes must be filtered to the current resource type only.");

            IEnumerable <ResourceProperty> navProperties =
                projectionNodesForCurrentResourceType == null
                ? this.Provider.GetResourceSerializableProperties(this.CurrentContainer, entityToSerialize.ResourceType).Where(p => p.TypeKind == ResourceTypeKind.EntityType)
                : projectionNodesForCurrentResourceType.Where(p => p.Property != null && p.Property.TypeKind == ResourceTypeKind.EntityType).Select(p1 => p1.Property);

            foreach (ResourceProperty property in navProperties)
            {
                ResourcePropertyInfo navProperty = this.GetNavigationPropertyInfo(expanded, entityToSerialize.Entity, entityToSerialize.ResourceType, property);
                ODataNavigationLink  navLink     = this.GetNavigationLink(entityToSerialize, navProperty.Property);

                // WCF Data Services show performance degradation with JsonLight when entities have > 25 Navgations on writing entries
                // DEVNOTE: for performance reasons, if the link has no content due to the metadata level, and is not expanded
                // then don't tell ODataLib about it at all.
                if (navLink.Url == null && navLink.AssociationLinkUrl == null && !navProperty.Expand)
                {
                    continue;
                }

                var linkArgs = new DataServiceODataWriterNavigationLinkArgs(navLink, this.Service.OperationContext);
                this.dataServicesODataWriter.WriteStart(linkArgs);

                if (navProperty.Expand)
                {
                    object          navPropertyValue          = navProperty.Value;
                    IExpandedResult navPropertyExpandedResult = navPropertyValue as IExpandedResult;
                    object          expandedPropertyValue     =
                        navPropertyExpandedResult != null?
                        GetExpandedElement(navPropertyExpandedResult) :
                            navPropertyValue;

                    bool needPop = this.PushSegmentForProperty(navProperty.Property, entityToSerialize.ResourceType, navProperty.ExpandedNode);

                    // if this.CurrentContainer is null, the target set of the navigation property is hidden.
                    if (this.CurrentContainer != null)
                    {
                        if (navProperty.Property.Kind == ResourcePropertyKind.ResourceSetReference)
                        {
                            IEnumerable enumerable;
                            bool        collection = WebUtil.IsElementIEnumerable(expandedPropertyValue, out enumerable);
                            Debug.Assert(collection, "metadata loading must have ensured that navigation set properties must implement IEnumerable");

                            QueryResultInfo queryResults = new QueryResultInfo(enumerable);
                            try
                            {
                                queryResults.MoveNext();
                                Func <Uri> getNavPropertyRelativeUri = () => RequestUriProcessor.AppendUnescapedSegment(entityToSerialize.SerializedKey.RelativeEditLink, navLink.Name);
                                Func <Uri> getNavPropertyAbsoluteUri = () => RequestUriProcessor.AppendUnescapedSegment(entityToSerialize.SerializedKey.AbsoluteEditLink, navLink.Name);
                                this.WriteFeedElements(navPropertyExpandedResult, queryResults, navProperty.Property.ResourceType, navLink.Name, getNavPropertyRelativeUri, getNavPropertyAbsoluteUri, false);
                            }
                            finally
                            {
                                // After the navigation property is completely serialized, dispose the property value.
                                WebUtil.Dispose(queryResults);
                            }
                        }
                        else if (WebUtil.IsNullValue(expandedPropertyValue))
                        {
                            // Write a null reference navigation property
                            var entryArgs = new DataServiceODataWriterEntryArgs(null, null, this.Service.OperationContext);
                            this.dataServicesODataWriter.WriteStart(entryArgs);
                            this.dataServicesODataWriter.WriteEnd(entryArgs);
                        }
                        else
                        {
                            this.WriteEntry(navPropertyExpandedResult, expandedPropertyValue, resourceInstanceInFeed, navProperty.Property.ResourceType);
                        }
                    }

                    this.PopSegmentName(needPop);
                }

                this.dataServicesODataWriter.WriteEnd(linkArgs); // end of navigation property
            }
        }
示例#25
0
        /// <summary>
        /// Write out the uri for the given elements.
        /// </summary>
        /// <param name="elements">Elements whose uri need to be written out.</param>
        private void WriteLinkCollection(QueryResultInfo elements)
        {
            ODataEntityReferenceLinks linksCollection = new ODataEntityReferenceLinks();

            // write count?
            if (this.RequestDescription.CountOption == RequestQueryCountOption.CountQuery)
            {
                linksCollection.Count = this.RequestDescription.CountValue;
            }

            // assign the links collection
            linksCollection.Links = this.GetLinksCollection(elements, linksCollection);

            this.writer.WriteEntityReferenceLinks(linksCollection);
        }