Exemple #1
0
        /// <summary>
        /// Verifies the named streams.
        /// </summary>
        /// <param name="dataContext">The data context.</param>
        /// <param name="queryEntityValue">The query entity value.</param>
        /// <param name="streamProperty">The stream property.</param>
        /// <param name="ed">The entity descriptor</param>
        /// <param name="continuation">The stream descriptor continuation.</param>
        private void VerifyNamedStreams(DataServiceContext dataContext, QueryStructuralValue queryEntityValue, QueryProperty streamProperty, EntityDescriptor ed, IAsyncContinuation continuation)
        {
            var expectedStreamValue = queryEntityValue.GetStreamValue(streamProperty.Name);
            var streamDescriptor    = ed.StreamDescriptors.SingleOrDefault(s => s.StreamLink.Name == streamProperty.Name);

            this.Assert.IsNotNull(streamDescriptor, "Entity missing stream descriptor for stream '{0}'", streamProperty.Name);
            this.VerifyStreamLink(expectedStreamValue, streamDescriptor.StreamLink);

            var expectedReadStreamUri = GetExpectedReadStreamUri(expectedStreamValue);

            Uri readStreamUri = dataContext.GetReadStreamUri(ed.Entity, streamProperty.Name);

            this.Assert.AreEqual(expectedReadStreamUri, readStreamUri, "Read stream uri did not match for stream '{0}'", streamProperty.Name);

            dataContext.GetReadStream(
                continuation,
                this.isAsynchronous,
                ed.Entity,
                streamProperty.Name,
                new DataServiceRequestArgs()
            {
            },
                response =>
            {
                UpdateStreamValueFromHeaders(expectedStreamValue, response);
                this.VerifyStreamLink(expectedStreamValue, streamDescriptor.StreamLink);
                // skip this verification when using payload driven verification since we don't have the expected content for streams
                if (!this.DataProviderSettings.UsePayloadDrivenVerification)
                {
                    this.Assert.IsTrue(this.VerifyStreams(expectedStreamValue, response), "Failed to compare value of stream '{0}'", streamProperty.Name);
                }

                continuation.Continue();
            });
        }
Exemple #2
0
        /// <summary>
        /// Verifies the default stream.
        /// </summary>
        /// <param name="dataContext">The data context.</param>
        /// <param name="queryEntityValue">The query entity value.</param>
        /// <param name="ed">The entity descriptor.</param>
        /// <param name="continuation">The stream descriptor continuation.</param>
        private void VerifyDefaultStream(DataServiceContext dataContext, QueryStructuralValue queryEntityValue, EntityDescriptor ed, IAsyncContinuation continuation)
        {
            var expectedStreamValue = queryEntityValue.GetDefaultStreamValue();

            this.VerifyStreamDescriptorValues(expectedStreamValue, null, null, ed.StreamETag, ed.EditStreamUri, ed.ReadStreamUri);

            var expectedReadStreamUri = GetExpectedReadStreamUri(expectedStreamValue);

            Uri readStreamUri = dataContext.GetReadStreamUri(ed.Entity);

            this.Assert.AreEqual(expectedReadStreamUri, readStreamUri, "Read stream uri did not match for default stream");

            dataContext.GetReadStream(
                continuation,
                this.isAsynchronous,
                ed.Entity,
                null,
                new DataServiceRequestArgs()
            {
            },
                response =>
            {
                UpdateStreamValueFromHeaders(expectedStreamValue, response);

                this.VerifyStreamDescriptorValues(expectedStreamValue, null, null, ed.StreamETag, ed.EditStreamUri, ed.ReadStreamUri);

                // skip this verification when using payload driven verification since we don't have the expected content for streams
                if (!this.DataProviderSettings.UsePayloadDrivenVerification)
                {
                    this.Assert.IsTrue(this.VerifyStreams(expectedStreamValue, response), "Failed to compare the default stream");
                }

                continuation.Continue();
            });
        }
        public void NamedStreams_DeepLinkProjection()
        {
            // projecting out deep links to get stream url in DSSL property - both narrow type and anonymous type
            {
                // Querying url of the nested type - doing this makes the entity non-tracking, but populated the link property
                DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                context.EnableAtom = true;
                context.Format.UseAtom();
                var q = from s in context.CreateQuery <EntityWithNamedStreams1>("MySet1")
                        select new
                {
                    ID  = s.Ref.ID,
                    Url = s.Ref.RefStream1
                };

                Assert.AreEqual(request.ServiceRoot.AbsoluteUri + "/MySet1?$expand=Ref($select=ID),Ref($select=RefStream1)", q.ToString(), "make sure the right uri is produced by the linq translator");

                foreach (var o in q)
                {
                    Assert.IsNotNull(o.Url, "Stream11 must have some value");
                    Assert.AreEqual(o.Url.EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet2(3)/RefStream1", "the stream url must be populated correctly");
                    Assert.IsNull(context.GetEntityDescriptor(o), "the entity must not be tracked by the context since we are trying to flatten the hierarchy");
                }

                Assert.AreEqual(context.Entities.Count, 0, "there should be no entities tracked by the context, since we are doing flattening");
            }

            {
                // Querying url of the nested type - doing this makes the entity non-tracking, but populated the link property
                DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                context.EnableAtom = true;
                context.Format.UseAtom();
                var q = from s in context.CreateQuery <EntityWithNamedStreams1>("MySet1")
                        select new EntityWithNamedStreams1
                {
                    ID         = s.Ref.ID,
                    RefStream1 = s.Ref.RefStream1
                };

                Assert.AreEqual(request.ServiceRoot.AbsoluteUri + "/MySet1?$expand=Ref($select=ID),Ref($select=RefStream1)", q.ToString(), "make sure the right uri is produced by the linq translator");

                foreach (var o in q)
                {
                    Assert.IsNotNull(o.RefStream1, "Stream11 must have some value");
                    Assert.AreEqual(o.RefStream1.EditLink, context.GetReadStreamUri(o, "RefStream1"), "the stream url must be populated correctly");
                }

                Assert.AreEqual(context.Entities.Count, 1, "there should be exactly one entity tracked by the context - the nested entity");
                Assert.AreEqual(context.Entities[0].EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet2(3)", "the nested entity is the one that should be tracked");
            }
        }
        public void NamedStreams_DeepLinkProjection_MultipleParametersInScope()
        {
            // projecting out deep links to get stream url in DSSL property with multiple parameters in scope - both narrow type and anonymous type
            {
                // Querying url of the nested type - doing this makes the entity non-tracking, but populated the link property
                DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                context.EnableAtom = true;
                context.Format.UseAtom();
                var q = from s in context.CreateQuery <EntityWithNamedStreams1>("MySet1")
                        where s.ID == 1
                        from c in s.Collection
                        select new
                {
                    Name = c.Name,
                    Url  = c.ColStream
                };

                Assert.AreEqual(q.ToString(), request.ServiceRoot.AbsoluteUri + "/MySet1(1)/Collection?$select=Name,ColStream", "make sure the right uri is produced by the linq translator");

                var entities = q.ToList();

                // Since there is SDP turned on, the inner collection returns only 1 entity.
                Assert.AreEqual(entities[0].Url.EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet3('ABCDE')/ColStream", "the stream url must be populated correctly - index 0");
                Assert.AreEqual(context.Entities.Count, 0, "there should be no entities tracked by the context, since we are doing flattening");
            }

            {
                // Querying url of the nested type - doing this makes the entity non-tracking, but populated the link property
                DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                context.EnableAtom = true;
                context.Format.UseAtom();
                var q = from s in context.CreateQuery <EntityWithNamedStreams1>("MySet1")
                        where s.ID == 1
                        from c in s.Collection
                        select new EntityWithNamedStreams2()
                {
                    ID        = c.ID,
                    ColStream = c.ColStream
                };

                Assert.AreEqual(q.ToString(), request.ServiceRoot.AbsoluteUri + "/MySet1(1)/Collection?$select=ID,ColStream", "make sure the right uri is produced by the linq translator");

                var entities = q.ToList();

                // Since there is SDP turned on, the inner collection returns only 1 entity.
                Assert.AreEqual(entities[0].ColStream.EditLink, context.GetReadStreamUri(entities[0], "ColStream"), "the stream url must be populated correctly - index 0");
                Assert.AreEqual(context.Entities.Count, 1, "there should be no entities tracked by the context, since we are doing flattening");
            }
        }
        public void NamedStreams_SimpleLinkProjection()
        {
            // Simple projections to get stream url in DSSL property - both narrow type and anonymous type
            {
                // Testing querying anonymous types and making sure one is able to project out the stream url
                DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                context.EnableAtom = true;
                context.Format.UseAtom();
                var q = from s in context.CreateQuery <EntityWithNamedStreams1>("MySet1")
                        select new
                {
                    ID       = s.ID,
                    Stream11 = s.Stream1
                };

                Assert.AreEqual(q.ToString(), request.ServiceRoot.AbsoluteUri + "/MySet1?$select=ID,Stream1", "make sure the right uri is produced by the linq translator");
                foreach (var o in q)
                {
                    Assert.IsNotNull(o.Stream11, "Stream11 must have some value");
                    Assert.AreEqual(o.Stream11.EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet1(1)/Stream1", "make sure the url property is correctly populated");
                    Assert.IsNull(context.GetEntityDescriptor(o), "anonymous types are never tracked, even if we do a simple projection");
                }

                Assert.AreEqual(context.Entities.Count, 0, "there should be no entity tracked by the context");
            }

            {
                // Testing querying narrow entity types and making sure one is able to project out the stream url
                DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                context.EnableAtom = true;
                context.Format.UseAtom();
                var q = from s in context.CreateQuery <EntityWithNamedStreams1>("MySet1")
                        select new EntityWithNamedStreams1
                {
                    ID      = s.ID,
                    Stream1 = s.Stream1
                };

                Assert.AreEqual(q.ToString(), request.ServiceRoot.AbsoluteUri + "/MySet1?$select=ID,Stream1", "make sure the right uri is produced by the linq translator");
                foreach (EntityWithNamedStreams1 o in q)
                {
                    Assert.IsNotNull(o.Stream1, "Stream11 must have some value");
                    Assert.AreEqual(o.Stream1.EditLink, context.GetReadStreamUri(o, "Stream1"), "the value in the entity descriptor must match with the property value");
                }

                Assert.AreEqual(context.Entities.Count, 1, "there should be only one entity tracked by the context");
            }
        }
        public void NamedStreams_PayloadDrivenMaterialization()
        {
            // Make sure DSSL properties can materialized and populated with the right url in non-projection cases
            {
                // Testing without projections (payload driven) and making sure one is able to project out the stream url
                DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                context.EnableAtom = true;
                context.Format.UseAtom();
                context.IgnoreMissingProperties = true;
                var    q      = context.CreateQuery <EntityWithStreamLink>("MySet1");
                object entity = null;

                foreach (EntityWithStreamLink o in q)
                {
                    Assert.IsNotNull(o.Stream1, "Stream1 must have some value");
                    Assert.AreEqual(o.Stream1.EditLink, context.GetReadStreamUri(o, "Stream1"), "the value in the entity descriptor must match with the property value");
                    Assert.IsNull(o.SomeRandomProperty, "SomeRandomProperty must be null, since the payload does not have the link with the property name");
                    entity = o;
                }

                // Try updating the entity and make sure that the link is not send back in the payload.
                context.UpdateObject(entity);

                WrappingStream wrappingStream = null;
                context.RegisterStreamCustomizer((inputStream) =>
                {
                    wrappingStream = new WrappingStream(inputStream);
                    return(wrappingStream);
                },
                                                 null);

                try
                {
                    context.SaveChanges();
                    Assert.Fail("Save changes should throw an exception");
                }
                catch (Exception)
                {
                    // do nothing
                }

                string payload = wrappingStream.GetLoggingStreamAsString();
                Assert.IsTrue(payload.Contains("<d:ID m:type=\"Int32\">1</d:ID>"), "Id element must be present");
                Assert.IsFalse(payload.Contains("Stream1Url"), "link url should not be sent in the payload");
            }
        }
        public void NamedStreams_NestedQuery_2()
        {
            // projecting out collection of collection properties - both narrow type and anonymous type
            {
                // Querying url of the nested type - doing this makes the entity non-tracking, but populated the link property
                DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                context.EnableAtom = true;
                context.Format.UseAtom();
                DataServiceQuery <EntityWithNamedStreams1> q = (DataServiceQuery <EntityWithNamedStreams1>) from s in context.CreateQuery <EntityWithNamedStreams1>("MySet1")
                                                               select new EntityWithNamedStreams1
                {
                    ID         = s.ID,
                    Stream1    = s.Stream1,
                    Collection = (from c in s.Collection
                                  select new EntityWithNamedStreams2()
                    {
                        ID = c.ID,
                        ColStream = c.ColStream,
                        Collection1 = (from c1 in c.Collection1
                                       select new EntityWithNamedStreams1()
                        {
                            ID = c1.ID,
                            RefStream1 = c1.RefStream1
                        }).ToList()
                    }).ToList()
                };

                Assert.AreEqual(request.ServiceRoot.AbsoluteUri + "/MySet1?$expand=Collection($select=ID),Collection($select=ColStream),Collection($expand=Collection1($select=ID)),Collection($expand=Collection1($select=RefStream1))&$select=ID,Stream1", q.ToString(), "make sure the right uri is produced by the linq translator");

                var response = (QueryOperationResponse <EntityWithNamedStreams1>)q.Execute();
                DataServiceQueryContinuation <EntityWithNamedStreams2> continuation = null;
                foreach (var o in response)
                {
                    Assert.IsNotNull(o.Stream1.EditLink, "Stream1 should not be null");
                    Assert.AreEqual(o.Stream1.EditLink, context.GetReadStreamUri(o, "Stream1"), "the stream url for Stream1 must be populated correctly");
                    foreach (var c in o.Collection)
                    {
                        Assert.IsNotNull(c.ColStream.EditLink, "ColStream should not be null");
                        Assert.AreEqual(c.ColStream.EditLink, context.GetReadStreamUri(c, "ColStream"), "the url for the nested collection entity should match - Level 0");
                        foreach (var c1 in c.Collection1)
                        {
                            Assert.IsNotNull(c1.RefStream1.EditLink, "RefStream1 should not be null");
                            Assert.AreEqual(c1.RefStream1.EditLink, context.GetReadStreamUri(c1, "RefStream1"), "the url for the nested collection entity should match - Level 1");
                        }
                    }

                    // Make sure you get the continuation token for the collection and try and get the next page
                    continuation = response.GetContinuation(o.Collection);
                }

                Assert.AreEqual(context.Entities.Count, 3, "there should be 3 entities tracked by the context");
                Assert.AreEqual(context.Entities[0].EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet1(1)", "top level entity must be tracked");
                Assert.AreEqual(context.Entities[1].EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet3('ABCDE')", "top level entity must be tracked");
                Assert.AreEqual(context.Entities[2].EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet2(3)", "the nested entity must be tracked");
                Assert.IsNotNull(continuation, "since SDP is turned on, we should get the continuation token");

                // Get the next page and make sure we get the right entity and the link is populated.
                foreach (var entity in context.Execute(continuation))
                {
                    Assert.IsNotNull(entity.ColStream.EditLink, "ColStream should not be null");
                    Assert.AreEqual(entity.ColStream.EditLink, context.GetReadStreamUri(entity, "ColStream"), "the url for the nested collection entity should match - Level 1");
                    foreach (var c1 in entity.Collection1)
                    {
                        Assert.IsNotNull(c1.RefStream1.EditLink, "RefStream1 should not be null");
                        Assert.AreEqual(c1.RefStream1.EditLink, context.GetReadStreamUri(c1, "RefStream1"), "the url for the nested collection entity should match - Level 1");
                    }
                }

                Assert.AreEqual(context.Entities.Count, 4, "there should be 4 entities tracked by the context");
            }

            {
                // Querying url of the nested type - doing this makes the entity non-tracking, but populated the link property
                DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                context.EnableAtom = true;
                context.Format.UseAtom();
                var q = from s in context.CreateQuery <EntityWithNamedStreams1>("MySet1")
                        select new
                {
                    ID         = s.ID,
                    Stream1Url = s.Stream1,
                    Collection = (from c in s.Collection
                                  select new
                    {
                        Name = c.Name,
                        Stream1Url = c.ColStream,
                        Collection1 = (from c1 in c.Collection1
                                       select new
                        {
                            ID = c1.ID,
                            Stream1Url = c1.RefStream1
                        })
                    })
                };

                Assert.AreEqual(request.ServiceRoot.AbsoluteUri + "/MySet1?$expand=Collection($select=Name),Collection($select=ColStream),Collection($expand=Collection1($select=ID)),Collection($expand=Collection1($select=RefStream1))&$select=ID,Stream1", q.ToString(), "make sure the right uri is produced by the linq translator");

                foreach (var o in q)
                {
                    Assert.AreEqual(o.Stream1Url.EditLink, request.ServiceRoot.AbsoluteUri + "/MySet1(1)/Stream1", "the stream url for Stream1 must be populated correctly");
                    Assert.AreEqual(o.Collection.First().Stream1Url.EditLink, request.ServiceRoot.AbsoluteUri + "/MySet3('ABCDE')/ColStream", "the stream url of the collection stream must be populated correctly - index 0");
                    Assert.AreEqual(o.Collection.First().Collection1.Single().Stream1Url.EditLink, request.ServiceRoot.AbsoluteUri + "/MySet2(3)/RefStream1", "the stream url of the collection stream must be populated correctly - index 0 - index 0");
                }

                Assert.AreEqual(context.Entities.Count, 0, "there should be no entities tracked by the context");
            }
        }
        public void NamedStreams_NestedQuery_1()
        {
            // projecting out deep links to get stream url in DSSL property - both narrow type and anonymous type
            {
                // Querying url of the nested type - doing this makes the entity non-tracking, but populated the link property
                DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                context.EnableAtom = true;
                context.Format.UseAtom();
                var q = from s in context.CreateQuery <EntityWithNamedStreams1>("MySet1")
                        select new EntityWithNamedStreams1
                {
                    ID      = s.ID,
                    Stream1 = s.Stream1,
                    Ref     = new EntityWithNamedStreams1
                    {
                        ID         = s.Ref.ID,
                        RefStream1 = s.Ref.RefStream1
                    },
                    Collection = (from c in s.Collection
                                  select new EntityWithNamedStreams2()
                    {
                        ID = c.ID,
                        ColStream = c.ColStream
                    }).ToList()
                };

                Assert.AreEqual(request.ServiceRoot.AbsoluteUri + "/MySet1?$expand=Ref($select=ID),Ref($select=RefStream1),Collection($select=ID),Collection($select=ColStream)&$select=ID,Stream1", q.ToString(), "make sure the right uri is produced by the linq translator");

                foreach (var o in q)
                {
                    Assert.IsNotNull(o.Stream1, "Stream11 must have some value");
                    Assert.AreEqual(o.Stream1.EditLink, context.GetReadStreamUri(o, "Stream1"), "the stream url for Stream1 must be populated correctly");
                    Assert.AreEqual(o.Ref.RefStream1.EditLink, context.GetReadStreamUri(o.Ref, "RefStream1"), "the stream url for RefStream1 must be populated correctly");
                    foreach (var c in o.Collection)
                    {
                        Assert.AreEqual(c.ColStream.EditLink, context.GetReadStreamUri(c, "ColStream"), "the url for the nested collection entity should match");
                    }
                }

                Assert.AreEqual(context.Entities.Count, 3, "there should be 3 entities tracked by the context");
                Assert.AreEqual(context.Entities[0].EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet1(1)", "top level entity must be tracked");
                Assert.AreEqual(context.Entities[1].EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet2(3)", "the nested entity must be tracked");
                Assert.AreEqual(context.Entities[2].EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet3('ABCDE')", "top level entity must be tracked");
            }

            {
                // Querying url of the nested type - doing this makes the entity non-tracking, but populated the link property
                DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                context.EnableAtom = true;
                context.Format.UseAtom();
                var q = from s in context.CreateQuery <EntityWithNamedStreams1>("MySet1")
                        select new
                {
                    ID         = s.ID,
                    Stream1Url = s.Stream1,
                    Ref        = new
                    {
                        ID         = s.Ref.ID,
                        Stream1Url = s.Ref.RefStream1
                    },
                    Collection = (from c in s.Collection
                                  select new
                    {
                        Name = c.Name,
                        Stream1Url = c.ColStream
                    })
                };

                Assert.AreEqual(request.ServiceRoot.AbsoluteUri + "/MySet1?$expand=Ref($select=ID),Ref($select=RefStream1),Collection($select=Name),Collection($select=ColStream)&$select=ID,Stream1", q.ToString(), "make sure the right uri is produced by the linq translator");

                foreach (var o in q)
                {
                    Assert.AreEqual(o.Stream1Url.EditLink, request.ServiceRoot.AbsoluteUri + "/MySet1(1)/Stream1", "the stream url for Stream1 must be populated correctly");
                    Assert.AreEqual(o.Ref.Stream1Url.EditLink, request.ServiceRoot.AbsoluteUri + "/MySet2(3)/RefStream1", "the stream url for RefStream1 must be populated correctly");
                    Assert.AreEqual(o.Collection.First().Stream1Url.EditLink, request.ServiceRoot.AbsoluteUri + "/MySet3('ABCDE')/ColStream", "the stream url of the collection stream must be populated correctly - index 0");
                }

                Assert.AreEqual(context.Entities.Count, 0, "there should be no entities tracked by the context");
            }
        }
        public void NamedStreams_DeepLinkProjection()
        {
            // projecting out deep links to get stream url in DSSL property - both narrow type and anonymous type
            {
                // Querying url of the nested type - doing this makes the entity non-tracking, but populated the link property
                DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                context.EnableAtom = true;
                context.Format.UseAtom();
                var q = from s in context.CreateQuery<EntityWithNamedStreams1>("MySet1")
                        select new
                        {
                            ID = s.Ref.ID,
                            Url = s.Ref.RefStream1
                        };

                Assert.AreEqual(request.ServiceRoot.AbsoluteUri + "/MySet1?$expand=Ref($select=ID),Ref($select=RefStream1)", q.ToString(), "make sure the right uri is produced by the linq translator");

                foreach (var o in q)
                {
                    Assert.IsNotNull(o.Url, "Stream11 must have some value");
                    Assert.AreEqual(o.Url.EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet2(3)/RefStream1", "the stream url must be populated correctly");
                    Assert.IsNull(context.GetEntityDescriptor(o), "the entity must not be tracked by the context since we are trying to flatten the hierarchy");
                }

                Assert.AreEqual(context.Entities.Count, 0, "there should be no entities tracked by the context, since we are doing flattening");
            }

            {
                // Querying url of the nested type - doing this makes the entity non-tracking, but populated the link property
                DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                context.EnableAtom = true;
                context.Format.UseAtom();
                var q = from s in context.CreateQuery<EntityWithNamedStreams1>("MySet1")
                        select new EntityWithNamedStreams1
                        {
                            ID = s.Ref.ID,
                            RefStream1 = s.Ref.RefStream1
                        };

                Assert.AreEqual(request.ServiceRoot.AbsoluteUri + "/MySet1?$expand=Ref($select=ID),Ref($select=RefStream1)", q.ToString(), "make sure the right uri is produced by the linq translator");

                foreach (var o in q)
                {
                    Assert.IsNotNull(o.RefStream1, "Stream11 must have some value");
                    Assert.AreEqual(o.RefStream1.EditLink, context.GetReadStreamUri(o, "RefStream1"), "the stream url must be populated correctly");
                }

                Assert.AreEqual(context.Entities.Count, 1, "there should be exactly one entity tracked by the context - the nested entity");
                Assert.AreEqual(context.Entities[0].EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet2(3)", "the nested entity is the one that should be tracked");
            }
        }
        public void VerifyMissingLinkQueryScenario()
        {
            // Make sure the query scenarios fail, when self/edit links for named stream is missing
            TestUtil.RunCombinations(
                UnitTestsUtil.BooleanValues,
                UnitTestsUtil.BooleanValues,
                UnitTestsUtil.BooleanValues,
                (syncRead, hasSelfLink, hasEditLink) =>
                {
                    using (PlaybackService.OverridingPlayback.Restore())
                    {
                        DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                        context.EnableAtom = true;

                        string links = null;
                        string contentType = null;
                        string selfLink = null;
                        string editLink = null;

                        if (hasSelfLink)
                        {
                            selfLink = request.ServiceRoot + "/Customers(1)/SelfLink/Thumbnail";
                            links += GetNamedStreamSelfLink(selfLink);
                        }

                        if (hasEditLink)
                        {
                            editLink = request.ServiceRoot + "/Customers(1)/EditLink/Thumbnail";
                            contentType = MediaContentType;
                            links += GetNamedStreamEditLink(editLink, contentType);
                        }

                        string payload = AtomParserTests.AnyEntry(
                                     id: Id,
                                     selfLink: request.ServiceRoot.AbsoluteUri + "/selfLink/Customers(1)",
                                     editLink: request.ServiceRoot.AbsoluteUri + "/editLink/Customers(1)",
                                     properties: Properties,
                                     links: links);

                        PlaybackService.OverridingPlayback.Value = PlaybackService.ConvertToPlaybackServicePayload(null, payload);
                        Customer c = context.Execute<Customer>(new Uri("/Customers(1)", UriKind.Relative)).Single();
                        PlaybackService.OverridingPlayback.Value = null;

                        EntityDescriptor ed = context.Entities.Single();
                        StreamDescriptor ns = null;
                        bool expectException = false;

                        if (!hasEditLink && !hasSelfLink)
                        {
                            expectException = true;
                            Assert.AreEqual(0, ed.StreamDescriptors.Count, "No named streams should be present");
                        }
                        else
                        {
                            ns = ed.StreamDescriptors.Single();
                            Assert.AreEqual(ns.StreamLink.SelfLink, selfLink, "self link must match");
                            Assert.AreEqual(ns.StreamLink.EditLink, editLink, "edit link must match");
                            Assert.AreEqual(ns.StreamLink.ContentType, contentType, "content type must match");
                            Assert.AreEqual(context.GetReadStreamUri(c, ns.StreamLink.Name).AbsoluteUri, ns.StreamLink.SelfLink != null ? ns.StreamLink.SelfLink.AbsoluteUri : ns.StreamLink.EditLink.AbsoluteUri,
                                "Make sure that context.GetReadStreamUri returns the self link if present, otherwise returns edit link");
                        }

                        try
                        {
                            if (syncRead)
                            {
                                context.GetReadStream(c, "Thumbnail", new DataServiceRequestArgs() { ContentType = "image/jpeg" });
                            }
                            else
                            {
                                IAsyncResult result = context.BeginGetReadStream(c, "Thumbnail", new DataServiceRequestArgs() { ContentType = "image/jpeg" }, (r) =>
                                    {
                                        context.EndGetReadStream(r);
                                    },
                                    null);

                                if (!result.CompletedSynchronously)
                                {
                                    Assert.IsTrue(result.AsyncWaitHandle.WaitOne(new TimeSpan(0, 0, AstoriaUnitTests.TestConstants.MaxTestTimeout), false), "BeginExecute timeout");
                                }
                            }

                            Assert.IsTrue(!expectException, "should reach here when no exception is expected");
                            Assert.IsTrue(PlaybackService.LastPlayback.Contains("GET " + selfLink ?? editLink), "should use self link if present, otherwise editlink");
                        }
                        catch (ArgumentException ex)
                        {
                            Assert.IsTrue(expectException, "should get exception when expected");
                            ArgumentException expectedException = new ArgumentException(DataServicesClientResourceUtil.GetString("Context_EntityDoesNotContainNamedStream", "Thumbnail"), "name");
                            Assert.AreEqual(expectedException.Message, ex.Message, "Error message did not match");
                            Assert.AreEqual(0, ed.StreamDescriptors.Count, "No named streams should be present");
                        }
                    }
                });
        }
        public void GetReadStreamUri()
        {
            // passing invalid name should not throw an exception, instead should return null
            // Populate the context with a single customer instance
            string payload = AtomParserTests.AnyEntry(
                id: Id,
                properties: Properties);

            using (PlaybackService.OverridingPlayback.Restore())
            {
                PlaybackService.OverridingPlayback.Value = PlaybackService.ConvertToPlaybackServicePayload(null, payload);
                DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                context.EnableAtom = true;
                DataServiceQuery<Customer> q = (DataServiceQuery<Customer>)context.CreateQuery<Customer>("Customers").Where(c1 => c1.ID == 1);
                Customer c = ((IEnumerable<Customer>)DataServiceContextTestUtil.ExecuteQuery(context, q, QueryMode.AsyncExecute)).Single();

                // ask the uri for a random named stream
                Assert.IsNull(context.GetReadStreamUri(c, "random"), "DataServiceContext.GetReadStreamUri should not throw if the stream with the given name is not present");
            }
        }
        public void NamedStreams_TestPublicAPIParameters()
        {
            // Test public api parameters
            DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);

            #region GetReadStreamUri API
            DataServiceContextTestUtil.CheckArgumentNull("entity", () =>
            {
                context.GetReadStreamUri(null, "Thumbnail");
            });

            DataServiceContextTestUtil.CheckArgumentNull("name", () =>
            {
                context.GetReadStreamUri(new Customer(), null);
            });

            DataServiceContextTestUtil.CheckArgumentEmpty("name", () =>
            {
                context.GetReadStreamUri(new Customer(), "");
            });

            DataServiceContextTestUtil.VerifyInvalidRequest(typeof(InvalidOperationException), "Context_EntityNotContained", () =>
            {
                context.GetReadStreamUri(new Customer(), "Thumbnail");
            });
            #endregion GetReadStreamUri API

            #region BeginGetReadStream
            DataServiceContextTestUtil.CheckArgumentNull("entity", () =>
            {
                context.BeginGetReadStream(null, "Thumbnail", new DataServiceRequestArgs(), null, null);
            });

            DataServiceContextTestUtil.CheckArgumentNull("name", () =>
            {
                context.BeginGetReadStream(new Customer(), null, new DataServiceRequestArgs(), null, null);
            });

            DataServiceContextTestUtil.CheckArgumentEmpty("name", () =>
            {
                context.BeginGetReadStream(new Customer(), "", new DataServiceRequestArgs(), null, null);
            });

            DataServiceContextTestUtil.CheckArgumentNull("args", () =>
            {
                context.BeginGetReadStream(new Customer(), "Thumbnail", null, null, null);
            });

            DataServiceContextTestUtil.VerifyInvalidRequest(typeof(InvalidOperationException), "Context_EntityNotContained", () =>
            {
                context.BeginGetReadStream(new Customer(), "Thumbnail", new DataServiceRequestArgs(), null, null);
            });
            #endregion BeginGetReadStream

            #region GetReadStream
            DataServiceContextTestUtil.CheckArgumentNull("entity", () =>
            {
                context.GetReadStream(null, "Thumbnail", new DataServiceRequestArgs());
            });

            DataServiceContextTestUtil.CheckArgumentNull("name", () =>
            {
                context.GetReadStream(new Customer(), null, new DataServiceRequestArgs());
            });

            DataServiceContextTestUtil.CheckArgumentEmpty("name", () =>
            {
                context.GetReadStream(new Customer(), "", new DataServiceRequestArgs());
            });

            DataServiceContextTestUtil.CheckArgumentNull("args", () =>
            {
                context.GetReadStream(new Customer(), "Thumbnail", null);
            });

            DataServiceContextTestUtil.VerifyInvalidRequest(typeof(InvalidOperationException), "Context_EntityNotContained", () =>
            {
                context.GetReadStream(new Customer(), "Thumbnail", new DataServiceRequestArgs());
            });
            #endregion GetReadStream

            #region SetSaveStream
            DataServiceContextTestUtil.CheckArgumentNull("entity", () =>
            {
                context.SetSaveStream(null, "Thumbnail", new MemoryStream(), true, new DataServiceRequestArgs());
            });

            DataServiceContextTestUtil.CheckArgumentNull("name", () =>
            {
                context.SetSaveStream(new Customer(), null, new MemoryStream(), true, new DataServiceRequestArgs());
            });

            DataServiceContextTestUtil.CheckArgumentEmpty("name", () =>
            {
                context.SetSaveStream(new Customer(), "", new MemoryStream(), true, new DataServiceRequestArgs());
            });

            DataServiceContextTestUtil.CheckArgumentNull("stream", () =>
            {
                context.SetSaveStream(new Customer(), "Thumbnail", null, true, new DataServiceRequestArgs());
            });

            DataServiceContextTestUtil.CheckArgumentNull("args", () =>
            {
                context.SetSaveStream(new Customer(), "Thumbnail", new MemoryStream(), true, (DataServiceRequestArgs)null);
            });

            DataServiceContextTestUtil.CheckArgumentNull("contentType", () =>
            {
                context.SetSaveStream(new Customer(), "Thumbnail", new MemoryStream(), true, (string)null);
            });

            DataServiceContextTestUtil.CheckArgumentEmpty("contentType", () =>
            {
                context.SetSaveStream(new Customer(), "Thumbnail", new MemoryStream(), true, string.Empty);
            });

            DataServiceContextTestUtil.VerifyInvalidRequest(typeof(InvalidOperationException), "Context_EntityNotContained", () =>
            {
                context.SetSaveStream(new Customer(), "Thumbnail", new MemoryStream(), true, "image/jpeg");
            });

            DataServiceContextTestUtil.CheckArgumentException("Context_ContentTypeRequiredForNamedStream", () =>
            {
                context.SetSaveStream(new Customer(), "Thumbnail", new MemoryStream(), true, new DataServiceRequestArgs());
            }, "args");

            DataServiceContextTestUtil.CheckArgumentException("Context_ContentTypeRequiredForNamedStream", () =>
            {
                context.SetSaveStream(new Customer(), "Thumbnail", new MemoryStream(), true, new DataServiceRequestArgs() { ContentType = string.Empty });
            }, "args");

            DataServiceContextTestUtil.VerifyInvalidRequest(typeof(InvalidOperationException), "Context_EntityNotContained", () =>
            {
                context.SetSaveStream(new Customer(), "Thumbnail", new MemoryStream(), true, new DataServiceRequestArgs() { ContentType = "image/jpg" });
            });
            #endregion SetSaveStream
        }
        public void NamedStreams_SimpleLinkProjection()
        {
            // Simple projections to get stream url in DSSL property - both narrow type and anonymous type
            {
                // Testing querying anonymous types and making sure one is able to project out the stream url
                DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                context.EnableAtom = true;
                context.Format.UseAtom();
                var q = from s in context.CreateQuery<EntityWithNamedStreams1>("MySet1")
                        select new
                        {
                            ID = s.ID,
                            Stream11 = s.Stream1
                        };

                Assert.AreEqual(q.ToString(), request.ServiceRoot.AbsoluteUri + "/MySet1?$select=ID,Stream1", "make sure the right uri is produced by the linq translator");
                foreach (var o in q)
                {
                    Assert.IsNotNull(o.Stream11, "Stream11 must have some value");
                    Assert.AreEqual(o.Stream11.EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet1(1)/Stream1", "make sure the url property is correctly populated");
                    Assert.IsNull(context.GetEntityDescriptor(o), "anonymous types are never tracked, even if we do a simple projection");
                }

                Assert.AreEqual(context.Entities.Count, 0, "there should be no entity tracked by the context");
            }

            {
                // Testing querying narrow entity types and making sure one is able to project out the stream url
                DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                context.EnableAtom = true;
                context.Format.UseAtom();
                var q = from s in context.CreateQuery<EntityWithNamedStreams1>("MySet1")
                        select new EntityWithNamedStreams1
                        {
                            ID = s.ID,
                            Stream1 = s.Stream1
                        };

                Assert.AreEqual(q.ToString(), request.ServiceRoot.AbsoluteUri + "/MySet1?$select=ID,Stream1", "make sure the right uri is produced by the linq translator");
                foreach (EntityWithNamedStreams1 o in q)
                {
                    Assert.IsNotNull(o.Stream1, "Stream11 must have some value");
                    Assert.AreEqual(o.Stream1.EditLink, context.GetReadStreamUri(o, "Stream1"), "the value in the entity descriptor must match with the property value");
                }

                Assert.AreEqual(context.Entities.Count, 1, "there should be only one entity tracked by the context");
            }
        }
        public void NamedStreams_NestedQuery_2()
        {
            // projecting out collection of collection properties - both narrow type and anonymous type
            {
                // Querying url of the nested type - doing this makes the entity non-tracking, but populated the link property
                DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                context.EnableAtom = true;
                context.Format.UseAtom();
                DataServiceQuery<EntityWithNamedStreams1> q = (DataServiceQuery<EntityWithNamedStreams1>)from s in context.CreateQuery<EntityWithNamedStreams1>("MySet1")
                        select new EntityWithNamedStreams1
                        {
                            ID = s.ID,
                            Stream1 = s.Stream1,
                            Collection = (from c in s.Collection
                                          select new EntityWithNamedStreams2()
                                          {
                                              ID = c.ID,
                                              ColStream = c.ColStream,
                                              Collection1 = (from c1 in c.Collection1
                                                            select new EntityWithNamedStreams1()
                                                            {
                                                                ID = c1.ID,
                                                                RefStream1 = c1.RefStream1
                                                            }).ToList()
                                          }).ToList()
                        };

                Assert.AreEqual(request.ServiceRoot.AbsoluteUri + "/MySet1?$expand=Collection($select=ID),Collection($select=ColStream),Collection($expand=Collection1($select=ID)),Collection($expand=Collection1($select=RefStream1))&$select=ID,Stream1", q.ToString(), "make sure the right uri is produced by the linq translator");

                var response = (QueryOperationResponse<EntityWithNamedStreams1>)q.Execute();
                DataServiceQueryContinuation<EntityWithNamedStreams2> continuation = null;
                foreach (var o in response)
                {
                    Assert.IsNotNull(o.Stream1.EditLink, "Stream1 should not be null");
                    Assert.AreEqual(o.Stream1.EditLink, context.GetReadStreamUri(o, "Stream1"), "the stream url for Stream1 must be populated correctly");
                    foreach (var c in o.Collection)
                    {
                        Assert.IsNotNull(c.ColStream.EditLink, "ColStream should not be null");
                        Assert.AreEqual(c.ColStream.EditLink, context.GetReadStreamUri(c, "ColStream"), "the url for the nested collection entity should match - Level 0");
                        foreach (var c1 in c.Collection1)
                        {
                            Assert.IsNotNull(c1.RefStream1.EditLink, "RefStream1 should not be null");
                            Assert.AreEqual(c1.RefStream1.EditLink, context.GetReadStreamUri(c1, "RefStream1"), "the url for the nested collection entity should match - Level 1");
                        }
                    }

                    // Make sure you get the continuation token for the collection and try and get the next page
                    continuation = response.GetContinuation(o.Collection);
                }

                Assert.AreEqual(context.Entities.Count, 3, "there should be 3 entities tracked by the context");
                Assert.AreEqual(context.Entities[0].EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet1(1)", "top level entity must be tracked");
                Assert.AreEqual(context.Entities[1].EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet3('ABCDE')", "top level entity must be tracked");
                Assert.AreEqual(context.Entities[2].EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet2(3)", "the nested entity must be tracked");
                Assert.IsNotNull(continuation, "since SDP is turned on, we should get the continuation token");

                // Get the next page and make sure we get the right entity and the link is populated.
                foreach (var entity in context.Execute(continuation))
                {
                    Assert.IsNotNull(entity.ColStream.EditLink, "ColStream should not be null");
                    Assert.AreEqual(entity.ColStream.EditLink, context.GetReadStreamUri(entity, "ColStream"), "the url for the nested collection entity should match - Level 1");
                    foreach (var c1 in entity.Collection1)
                    {
                        Assert.IsNotNull(c1.RefStream1.EditLink, "RefStream1 should not be null");
                        Assert.AreEqual(c1.RefStream1.EditLink, context.GetReadStreamUri(c1, "RefStream1"), "the url for the nested collection entity should match - Level 1");
                    }
                }

                Assert.AreEqual(context.Entities.Count, 4, "there should be 4 entities tracked by the context");
            }

            {
                // Querying url of the nested type - doing this makes the entity non-tracking, but populated the link property
                DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                context.EnableAtom = true;
                context.Format.UseAtom();
                var q = from s in context.CreateQuery<EntityWithNamedStreams1>("MySet1")
                        select new
                        {
                            ID = s.ID,
                            Stream1Url = s.Stream1,
                            Collection = (from c in s.Collection
                                          select new
                                          {
                                              Name = c.Name,
                                              Stream1Url = c.ColStream,
                                              Collection1 = (from c1 in c.Collection1
                                                             select new
                                                             {
                                                                 ID = c1.ID,
                                                                 Stream1Url = c1.RefStream1
                                                             })
                                          })
                        };

                Assert.AreEqual(request.ServiceRoot.AbsoluteUri + "/MySet1?$expand=Collection($select=Name),Collection($select=ColStream),Collection($expand=Collection1($select=ID)),Collection($expand=Collection1($select=RefStream1))&$select=ID,Stream1", q.ToString(), "make sure the right uri is produced by the linq translator");

                foreach (var o in q)
                {
                    Assert.AreEqual(o.Stream1Url.EditLink, request.ServiceRoot.AbsoluteUri + "/MySet1(1)/Stream1", "the stream url for Stream1 must be populated correctly");
                    Assert.AreEqual(o.Collection.First().Stream1Url.EditLink, request.ServiceRoot.AbsoluteUri + "/MySet3('ABCDE')/ColStream", "the stream url of the collection stream must be populated correctly - index 0");
                    Assert.AreEqual(o.Collection.First().Collection1.Single().Stream1Url.EditLink, request.ServiceRoot.AbsoluteUri + "/MySet2(3)/RefStream1", "the stream url of the collection stream must be populated correctly - index 0 - index 0");
                }

                Assert.AreEqual(context.Entities.Count, 0, "there should be no entities tracked by the context");
            }
        }
        public void NamedStreams_NestedQuery_1()
        {
            // projecting out deep links to get stream url in DSSL property - both narrow type and anonymous type
            {
                // Querying url of the nested type - doing this makes the entity non-tracking, but populated the link property
                DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                context.EnableAtom = true;
                context.Format.UseAtom();
                var q = from s in context.CreateQuery<EntityWithNamedStreams1>("MySet1")
                        select new EntityWithNamedStreams1
                        {
                            ID = s.ID,
                            Stream1 = s.Stream1,
                            Ref = new EntityWithNamedStreams1
                            {
                                ID = s.Ref.ID,
                                RefStream1 = s.Ref.RefStream1
                            },
                            Collection = (from c in s.Collection
                                          select new EntityWithNamedStreams2()
                                          {
                                              ID = c.ID,
                                              ColStream = c.ColStream
                                          }).ToList()
                        };

                Assert.AreEqual(request.ServiceRoot.AbsoluteUri + "/MySet1?$expand=Ref($select=ID),Ref($select=RefStream1),Collection($select=ID),Collection($select=ColStream)&$select=ID,Stream1", q.ToString(), "make sure the right uri is produced by the linq translator");

                foreach (var o in q)
                {
                    Assert.IsNotNull(o.Stream1, "Stream11 must have some value");
                    Assert.AreEqual(o.Stream1.EditLink, context.GetReadStreamUri(o, "Stream1"), "the stream url for Stream1 must be populated correctly");
                    Assert.AreEqual(o.Ref.RefStream1.EditLink, context.GetReadStreamUri(o.Ref, "RefStream1"), "the stream url for RefStream1 must be populated correctly");
                    foreach (var c in o.Collection)
                    {
                        Assert.AreEqual(c.ColStream.EditLink, context.GetReadStreamUri(c, "ColStream"), "the url for the nested collection entity should match");
                    }
                }

                Assert.AreEqual(context.Entities.Count, 3, "there should be 3 entities tracked by the context");
                Assert.AreEqual(context.Entities[0].EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet1(1)", "top level entity must be tracked");
                Assert.AreEqual(context.Entities[1].EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet2(3)", "the nested entity must be tracked");
                Assert.AreEqual(context.Entities[2].EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet3('ABCDE')", "top level entity must be tracked");
            }

            {
                // Querying url of the nested type - doing this makes the entity non-tracking, but populated the link property
                DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                context.EnableAtom = true;
                context.Format.UseAtom();
                var q = from s in context.CreateQuery<EntityWithNamedStreams1>("MySet1")
                        select new
                        {
                            ID = s.ID,
                            Stream1Url = s.Stream1,
                            Ref = new
                            {
                                ID = s.Ref.ID,
                                Stream1Url = s.Ref.RefStream1
                            },
                            Collection = (from c in s.Collection
                                          select new
                                          {
                                              Name = c.Name,
                                              Stream1Url = c.ColStream
                                          })
                        };

                Assert.AreEqual(request.ServiceRoot.AbsoluteUri + "/MySet1?$expand=Ref($select=ID),Ref($select=RefStream1),Collection($select=Name),Collection($select=ColStream)&$select=ID,Stream1", q.ToString(), "make sure the right uri is produced by the linq translator");

                foreach (var o in q)
                {
                    Assert.AreEqual(o.Stream1Url.EditLink, request.ServiceRoot.AbsoluteUri + "/MySet1(1)/Stream1", "the stream url for Stream1 must be populated correctly");
                    Assert.AreEqual(o.Ref.Stream1Url.EditLink, request.ServiceRoot.AbsoluteUri + "/MySet2(3)/RefStream1", "the stream url for RefStream1 must be populated correctly");
                    Assert.AreEqual(o.Collection.First().Stream1Url.EditLink, request.ServiceRoot.AbsoluteUri + "/MySet3('ABCDE')/ColStream", "the stream url of the collection stream must be populated correctly - index 0");
                }

                Assert.AreEqual(context.Entities.Count, 0, "there should be no entities tracked by the context");
            }
        }
        public void NamedStreams_DeepLinkProjection_MultipleParametersInScope()
        {
            // projecting out deep links to get stream url in DSSL property with multiple parameters in scope - both narrow type and anonymous type
            {
                // Querying url of the nested type - doing this makes the entity non-tracking, but populated the link property
                DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                context.EnableAtom = true;
                context.Format.UseAtom();
                var q = from s in context.CreateQuery<EntityWithNamedStreams1>("MySet1")
                        where s.ID == 1
                        from c in s.Collection
                        select new
                        {
                            Name = c.Name,
                            Url = c.ColStream
                        };

                Assert.AreEqual(q.ToString(), request.ServiceRoot.AbsoluteUri + "/MySet1(1)/Collection?$select=Name,ColStream", "make sure the right uri is produced by the linq translator");

                var entities = q.ToList();

                // Since there is SDP turned on, the inner collection returns only 1 entity.
                Assert.AreEqual(entities[0].Url.EditLink.AbsoluteUri, request.ServiceRoot.AbsoluteUri + "/MySet3('ABCDE')/ColStream", "the stream url must be populated correctly - index 0");
                Assert.AreEqual(context.Entities.Count, 0, "there should be no entities tracked by the context, since we are doing flattening");
            }

            {
                // Querying url of the nested type - doing this makes the entity non-tracking, but populated the link property
                DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                context.EnableAtom = true;
                context.Format.UseAtom();
                var q = from s in context.CreateQuery<EntityWithNamedStreams1>("MySet1")
                        where s.ID == 1
                        from c in s.Collection
                        select new EntityWithNamedStreams2()
                        {
                            ID = c.ID,
                            ColStream = c.ColStream
                        };

                Assert.AreEqual(q.ToString(), request.ServiceRoot.AbsoluteUri + "/MySet1(1)/Collection?$select=ID,ColStream", "make sure the right uri is produced by the linq translator");

                var entities = q.ToList();

                // Since there is SDP turned on, the inner collection returns only 1 entity.
                Assert.AreEqual(entities[0].ColStream.EditLink, context.GetReadStreamUri(entities[0], "ColStream"), "the stream url must be populated correctly - index 0");
                Assert.AreEqual(context.Entities.Count, 1, "there should be no entities tracked by the context, since we are doing flattening");
            }
        }
Exemple #17
0
 public Uri GetReadStreamUri(object entity)
 {
     return(_context.GetReadStreamUri(entity));
 }
        public void NamedStreams_PayloadDrivenMaterialization()
        {
            // Make sure DSSL properties can materialized and populated with the right url in non-projection cases
            {
                // Testing without projections (payload driven) and making sure one is able to project out the stream url
                DataServiceContext context = new DataServiceContext(request.ServiceRoot, ODataProtocolVersion.V4);
                context.EnableAtom = true;
                context.Format.UseAtom();
                context.IgnoreMissingProperties = true;
                var q = context.CreateQuery<EntityWithStreamLink>("MySet1");
                object entity = null;

                foreach (EntityWithStreamLink o in q)
                {
                    Assert.IsNotNull(o.Stream1, "Stream1 must have some value");
                    Assert.AreEqual(o.Stream1.EditLink, context.GetReadStreamUri(o, "Stream1"), "the value in the entity descriptor must match with the property value");
                    Assert.IsNull(o.SomeRandomProperty, "SomeRandomProperty must be null, since the payload does not have the link with the property name");
                    entity = o;
                }

                // Try updating the entity and make sure that the link is not send back in the payload.
                context.UpdateObject(entity);

                WrappingStream wrappingStream = null;
                context.RegisterStreamCustomizer((inputStream) =>
                    {
                        wrappingStream = new WrappingStream(inputStream);
                        return wrappingStream;
                    },
                    null);

                try
                {
                    context.SaveChanges();
                    Assert.Fail("Save changes should throw an exception");
                }
                catch (Exception)
                {
                    // do nothing
                }

                string payload = wrappingStream.GetLoggingStreamAsString();
                Assert.IsTrue(payload.Contains("<d:ID m:type=\"Int32\">1</d:ID>"), "Id element must be present");
                Assert.IsFalse(payload.Contains("Stream1Url"), "link url should not be sent in the payload");
            }
        }