示例#1
30
        public void SingleChangesetShouldBeAtomic()
        {
            this.TestClientContext.MergeOption = MergeOption.OverwriteChanges;
            SaveChangesOptions[] options = new SaveChangesOptions[]
            {
                // All modifications share one changeset
                SaveChangesOptions.BatchWithSingleChangeset,

                // Each modification uses seperate changeset
                SaveChangesOptions.BatchWithIndependentOperations
            };

            Airline airline = new Airline()
            {
                Name = "American Delta",
                AirlineCode = "DL",
                TimeStampValue = new byte[] { 0 }
            };

            Airline airline1 = new Airline()
            {
                Name = "American Delta",
                AirlineCode = "DL",
                TimeStampValue = new byte[] { 0 }
            };

            Flight flight = new Flight()
            {
                ConfirmationCode = "JH58496",
                FlightNumber = "DL589",
                StartsAt = new DateTimeOffset(new DateTime(2014, 2, 10, 15, 00, 0)),
                EndsAt = new DateTimeOffset(new DateTime(2014, 2, 10, 16, 30, 0)),
                AirlineId = "DL",
                SeatNumber = "C32",
                FromId = "KSEA",
                ToId = "ZSSS",
                Airline = airline
            };

            foreach (var option in options)
            {
                this.TestClientContext.ResetDataSource().Execute();

                this.TestClientContext.AddToAirlines(airline);
                this.TestClientContext.AddToFlights(flight);
                // Post an entity with same ID, this would cause creation failture.
                this.TestClientContext.AddToAirlines(airline1);

                switch (option)
                {
                    case SaveChangesOptions.BatchWithIndependentOperations:
                        DataServiceResponse response1 = this.TestClientContext.SaveChanges(option);
                        Assert.Equal(200, response1.BatchStatusCode);
                        Assert.True(response1.IsBatchResponse);
                        Assert.Equal(3, response1.Count());
                        var result = response1.ToList();

                        // 3rd operation would fail, but new flight entry would be inserted.
                        Assert.Equal(201, result[0].StatusCode);
                        Assert.Equal(201, result[1].StatusCode);
                        Assert.Equal(500, result[2].StatusCode);
                        Assert.Equal(1,
                            this.TestClientContext
                                .Flights.Where(f => f.FlightNumber == flight.FlightNumber).ToList().Count);
                        break;
                    case SaveChangesOptions.BatchWithSingleChangeset:
                        bool exc = false;
                        try
                        {
                            // The single changeset would fail.
                            this.TestClientContext.SaveChanges(option);
                        }
                        catch (Exception)
                        {
                            exc = true;
                        }

                        Assert.True(exc);

                        Assert.Equal(0,
                            this.TestClientContext
                                .Flights.Where(f => f.FlightNumber == flight.FlightNumber).ToList().Count);
                        break;
                }


                this.TestClientContext.Detach(airline1);
                this.TestClientContext.Detach(airline);
                this.TestClientContext.Detach(flight);
            }
        }
示例#2
0
        public void CreateRelatedEntitesWithDifferentChangesetOptions()
        {
            this.TestClientContext.MergeOption = MergeOption.OverwriteChanges;
            SaveChangesOptions[] options = new SaveChangesOptions[]
            {
                // All modifications share one changeset
                SaveChangesOptions.BatchWithSingleChangeset,

                // Each modification uses seperate changeset
                SaveChangesOptions.BatchWithIndependentOperations
            };

            Airline airline = new Airline()
            {
                Name = "American Delta",
                AirlineCode = "DL",
                TimeStampValue = new byte[] { 0 }
            };

            Flight flight = new Flight()
            {
                ConfirmationCode = "JH58496",
                FlightNumber = "DL589",
                StartsAt = new DateTimeOffset(new DateTime(2014, 2, 10, 15, 00, 0)),
                EndsAt = new DateTimeOffset(new DateTime(2014, 2, 10, 16, 30, 0)),
                AirlineId = "DL",
                SeatNumber = "C32",
                FromId = "KSEA",
                ToId = "ZSSS",
                Airline = airline
            };

            foreach (var option in options)
            {
                this.TestClientContext.ResetDataSource().Execute();

                // This should fail for BatchWithIndependentOperations, as the foreign key restriction breaks.
                this.TestClientContext.AddToFlights(flight);
                this.TestClientContext.AddToAirlines(airline);
                this.TestClientContext.SendingRequest2 += (sender, e) =>
                {
                    e.RequestMessage.SetHeader("Prefer", "odata.continue-on-error");
                };

                DataServiceResponse response1 = this.TestClientContext.SaveChanges(option);

                switch (option)
                {
                    case SaveChangesOptions.BatchWithIndependentOperations:
                        
                        Assert.Equal(200, response1.BatchStatusCode);
                        Assert.True(response1.IsBatchResponse);
                        Assert.Equal(2, response1.Count());
                        var result1 = response1.ToList();
                        // fail for adding flight, but succeed for adding airlire
                        Assert.Equal(500, result1[0].StatusCode);
                        Assert.Equal(201, result1[1].StatusCode);
                        Assert.Equal(0,
                            this.TestClientContext
                                .Flights.Where(f => f.FlightNumber == flight.FlightNumber).ToList().Count);
                        break;
                    case SaveChangesOptions.BatchWithSingleChangeset:
                        Assert.Equal(200, response1.BatchStatusCode);
                        Assert.True(response1.IsBatchResponse);
                        Assert.Equal(2, response1.Count());
                        var result2 = response1.ToList();

                        // Both would succeed
                        Assert.Equal(201, result2[0].StatusCode);
                        Assert.Equal(201, result2[1].StatusCode);

                        Assert.Equal(1,
                            this.TestClientContext
                                .Flights.Where(f => f.FlightNumber == flight.FlightNumber).ToList().Count);
                        break;

                }

                this.TestClientContext.Detach(airline);
                this.TestClientContext.Detach(flight);
            }
        }
        public void CURDSingleNavigationPropertyAndRef()
        {
            this.TestClientContext.MergeOption = Microsoft.OData.Client.MergeOption.OverwriteChanges;

            Airline airline = new Airline()
            {
                Name = "American Delta",
                AirlineCode = "DL",
                TimeStampValue = new byte[] { 0 }
            };

            this.TestClientContext.AddToAirlines(airline);
            this.TestClientContext.SaveChanges();

            // Post an entity
            Flight flight = new Flight()
            {
                ConfirmationCode = "JH58496",
                FlightNumber = "DL589",
                StartsAt = new DateTimeOffset(new DateTime(2014, 2, 10, 15, 00, 0)),
                EndsAt = new DateTimeOffset(new DateTime(2014, 2, 10, 16, 30, 0)),
                AirlineId = null,
                SeatNumber = "C32",
                FromId = "KSEA",
                ToId = "ZSSS"
            };

            this.TestClientContext.AddToFlights(flight);
            this.TestClientContext.SaveChanges();

            // Set $ref
            this.TestClientContext.SetLink(flight, "Airline", airline);
            this.TestClientContext.SaveChanges();

            this.TestClientContext.Detach(airline);
            // Query an Navigation Property
            var airline2 = this.TestClientContext.Flights
                .ByKey(new Dictionary<string, object>() { { "FlightId", flight.FlightId } })
                .Airline.GetValue();
            Assert.Equal(airline.AirlineCode, airline2.AirlineCode);

            // Expand an Navigation Property
            var flight2 = this.TestClientContext.Flights
                .Expand(f => f.From)
                .Expand(f => f.To)
                .Where(f => f.FlightId == flight.FlightId)
                .SingleOrDefault();
            Assert.Equal(flight.FromId, flight2.From.IcaoCode);
            Assert.Equal(flight.ToId, flight2.To.IcaoCode);

            // Expand with select
            this.TestClientContext.Detach(flight2.From);
            var flight3 = this.TestClientContext.Flights
                .AddQueryOption("$expand", "From($select=IcaoCode)")
                .Where(f => f.FlightId == flight.FlightId)
                .SingleOrDefault();
            Assert.Equal(flight.FromId, flight3.From.IcaoCode);
            Assert.Null(flight3.From.IataCode);

            // Get $ref
            Dictionary<string, string> headers = new Dictionary<string, string>();
            ODataMessageReaderSettings readerSettings = new ODataMessageReaderSettings { BaseUri = this.TestClientContext.BaseUri };

            HttpWebRequestMessage request = new HttpWebRequestMessage(
                new DataServiceClientRequestMessageArgs(
                    "Get",
                    new Uri(string.Format(this.TestClientContext.BaseUri + "/Flights({0})/Airline/$ref", flight.FlightId),
                        UriKind.Absolute),
                    false,
                    false,
                    headers));

            using (HttpWebResponseMessage response = request.GetResponse() as HttpWebResponseMessage)
            {
                Assert.Equal(200, response.StatusCode);
                using (var stream = response.GetStream())
                {
                    StreamReader reader = new StreamReader(stream);
                    var expectedPayload = "{"
                        + @"  ""@odata.context"":""http://*****:*****@"""@odata.id"":""http://localhost:18384/api/Trippin/Airlines('{0}')""", airline2.AirlineCode)
                        + "}";
                    var content = reader.ReadToEnd();
                    Assert.Equal(expectedPayload.Replace(" ", ""), content);
                }
            }

            // Delete $ref
            this.TestClientContext.SetLink(flight, "Airline", null);
            this.TestClientContext.SaveChanges();

            this.TestClientContext.Detach(airline);

            HttpWebRequestMessage request2 = new HttpWebRequestMessage(
                new DataServiceClientRequestMessageArgs(
                    "Get",
                    new Uri(string.Format(this.TestClientContext.BaseUri + "/Flights({0})/Airline/$ref", flight.FlightId)
                        , UriKind.Absolute),
                    false,
                    false,
                    headers));

            DataServiceTransportException exception = null;

            try
            {
                request2.GetResponse();
            }
            catch (DataServiceTransportException e)
            {
                exception = e;
            }
            Assert.NotNull(exception);
            Assert.Equal(404, exception.Response.StatusCode);

            // TODO GitHubIssue#288 : 204 is expected.
            // Query an Navigation Property
            try
            {
                airline2 = this.TestClientContext.Flights.ByKey(new Dictionary<string, object>() { { "FlightId", flight.FlightId } }).Airline.GetValue();
            }
            catch (DataServiceQueryException e)
            {
                Assert.Equal(404, e.Response.StatusCode);
            }
        }
        public void ByteArrayIfMatchTest()
        {
            this.TestClientContext.MergeOption = MergeOption.OverwriteChanges;
            var airline = new Airline()
            {
                AirlineCode = "TT",
                Name = "Test Airlines"
            };

            this.TestClientContext.AddToAirlines(airline);
            this.TestClientContext.SaveChanges();

            string etag = null;
            int statusCode = -1;
            EventHandler<ReceivingResponseEventArgs> statusCodeHandler = (sender, eventArgs) =>
            {
                etag = eventArgs.ResponseMessage.GetHeader("ETag");
                statusCode = eventArgs.ResponseMessage.StatusCode;
            };

            this.TestClientContext.ReceivingResponse += statusCodeHandler;

            // Retrieve the matched etag
            airline =
                this.TestClientContext.Airlines.ByKey(new Dictionary<string, object>()
                {
                    {"AirlineCode", airline.AirlineCode}
                }).GetValue();
            var matchEtag = etag;

            // Retrieve a none match etag
            var anotherAirline =
                this.TestClientContext.Airlines.ByKey(new Dictionary<string, object>() {{"AirlineCode", "AA"}})
                    .GetValue();
            var nonMatchEtag = etag;

            // Delete the Entity with If-Match does not match, should return 412
            EventHandler<SendingRequest2EventArgs> sendRequestEvent = (sender, eventArgs) =>
            {
                eventArgs.RequestMessage.SetHeader("If-Match", nonMatchEtag);
            };

            this.TestClientContext.SendingRequest2 += sendRequestEvent;
            this.TestClientContext.DeleteObject(airline);
            Assert.Throws<DataServiceRequestException>(() => this.TestClientContext.SaveChanges());
            Assert.Equal(412, statusCode);

            // Delete the Entity with If-Match matches, should return 204
            this.TestClientContext.SendingRequest2 -= sendRequestEvent;
            sendRequestEvent = (sender, eventArgs) =>
            {
                eventArgs.RequestMessage.SetHeader("If-Match", matchEtag);
            };

            this.TestClientContext.SendingRequest2 += sendRequestEvent;
            this.TestClientContext.DeleteObject(airline);
            this.TestClientContext.SaveChanges();
            Assert.Equal(204, statusCode);

            // Query the flight again and entity does not exist.
            this.TestClientContext.SendingRequest2 -= sendRequestEvent;
            Assert.Throws<DataServiceQueryException>(() =>
                airline =
                    this.TestClientContext.Airlines.ByKey(new Dictionary<string, object>()
                    {
                        {"AirlineCode", airline.AirlineCode}
                    }).GetValue()
                );

            Assert.Equal(404, statusCode);
        }
        public void BatchRequest()
        {
            this.TestClientContext.MergeOption = Microsoft.OData.Client.MergeOption.OverwriteChanges;
            SaveChangesOptions[] options = new SaveChangesOptions[]
            {
                SaveChangesOptions.BatchWithSingleChangeset,
                SaveChangesOptions.BatchWithIndependentOperations
            };

            Airline airline = new Airline()
            {
                Name = "American Delta",
                AirlineCode = "DL",
                TimeStampValue = new byte[] { 0 }
            };

            // Post an entity
            Flight flight = new Flight()
            {
                ConfirmationCode = "JH58496",
                FlightNumber = "DL589",
                StartsAt = new DateTimeOffset(new DateTime(2014, 2, 10, 15, 00, 0)),
                EndsAt = new DateTimeOffset(new DateTime(2014, 2, 10, 16, 30, 0)),
                AirlineId = "DL",
                SeatNumber = "C32",
                FromId = "KSEA",
                ToId = "ZSSS"
            };

            foreach (var option in options)
            {
                this.TestClientContext.ResetDataSource().Execute();
                this.TestClientContext.AddToAirlines(airline);
                this.TestClientContext.AddToFlights(flight);
                DataServiceResponse response1 = this.TestClientContext.SaveChanges(option);
                if (response1.BatchStatusCode != 200)
                {
                    Assert.NotNull(response1);
                }
                Assert.True(response1.IsBatchResponse);
                foreach (OperationResponse item in response1)
                {
                    Assert.Equal(201, item.StatusCode);
                }
                Assert.Equal(2, response1.Count());

                this.TestClientContext.Detach(airline);
                this.TestClientContext.Detach(flight);

                var request1 = this.TestClientContext.Airlines.Where(al => al.AirlineCode == airline.AirlineCode) as DataServiceQuery<Airline>;
                var request2 = this.TestClientContext.Flights.Where(f => f.FlightId == flight.FlightId) as DataServiceQuery<Flight>;
                var response2 = this.TestClientContext.ExecuteBatch(new DataServiceRequest[] { request1, request2 });
                Assert.NotNull(response2);
                Assert.True(response2.IsBatchResponse);
                var resp2 = response2.ToList();
                Assert.Equal(2, resp2.Count());
                foreach (QueryOperationResponse item in resp2)
                {
                    Assert.Equal(200, item.StatusCode);
                }
                this.TestClientContext.Detach(airline);
                this.TestClientContext.Detach(flight);
            }
        }