private async Task RoundTripChanges <TBlog>()
            where TBlog : class, IBlog, new()
        {
            using (var testDatabase = OracleTestStore.CreateInitialized(DatabaseName))
            {
                var options = Fixture.CreateOptions(testDatabase);

                int blog1Id;
                int blog2Id;
                int blog3Id;

                using (var context = new BloggingContext <TBlog>(options))
                {
                    var blogs = await CreateBlogDatabaseAsync <TBlog>(context);

                    blog1Id = blogs[0].Id;
                    blog2Id = blogs[1].Id;

                    Assert.NotEqual(0, blog1Id);
                    Assert.NotEqual(0, blog2Id);
                    Assert.NotEqual(blog1Id, blog2Id);
                }

                using (var context = new BloggingContext <TBlog>(options))
                {
                    var blogs = context.Blogs.ToList();
                    Assert.Equal(2, blogs.Count);

                    var blog1 = blogs.Single(b => b.Name == "Blog1");
                    Assert.Equal(blog1Id, blog1.Id);

                    Assert.Equal("Blog1", blog1.Name);
                    Assert.True(blog1.George);
                    Assert.Equal(new Guid("0456AEF1-B7FC-47AA-8102-975D6BA3A9BF"), blog1.TheGu);
                    Assert.Equal(new DateTime(1973, 9, 3, 0, 10, 33, 777), blog1.NotFigTime);
                    Assert.Equal(64, blog1.ToEat);
                    Assert.Equal(0.123456789, blog1.OrNothing);
                    Assert.Equal(777, blog1.Fuse);
                    Assert.Equal(9876543210, blog1.WayRound);
                    Assert.Equal(0.12345f, blog1.Away);
                    Assert.Equal(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, blog1.AndChew);

                    blog1.Name = "New Name";

                    var blog2 = blogs.Single(b => b.Name == "Blog2");
                    Assert.Equal(blog2Id, blog2.Id);

                    blog2.Name       = null;
                    blog2.NotFigTime = new DateTime();
                    blog2.AndChew    = null;

                    var blog3 = context.Add(new TBlog()).Entity;

                    await context.SaveChangesAsync();

                    blog3Id = blog3.Id;
                    Assert.NotEqual(0, blog3Id);
                }

                using (var context = new BloggingContext <TBlog>(options))
                {
                    var blogs = context.Blogs.ToList();
                    Assert.Equal(3, blogs.Count);

                    Assert.Equal("New Name", blogs.Single(b => b.Id == blog1Id).Name);

                    var blog2 = blogs.Single(b => b.Id == blog2Id);
                    Assert.Null(blog2.Name);
                    Assert.Equal(blog2.NotFigTime, new DateTime());
                    Assert.Null(blog2.AndChew);

                    var blog3 = blogs.Single(b => b.Id == blog3Id);
                    Assert.Null(blog3.Name);
                    Assert.Equal(blog3.NotFigTime, new DateTime());
                    Assert.Null(blog3.AndChew);
                }
            }
        }
        public async Task Can_save_changes()
        {
            using (var testDatabase = OracleTestStore.CreateInitialized(DatabaseName))
            {
                var options = Fixture.CreateOptions(testDatabase);
                using (var db = new BloggingContext(options))
                {
                    await CreateBlogDatabaseAsync <Blog>(db);
                }

                Fixture.TestSqlLoggerFactory.Clear();

                using (var db = new BloggingContext(options))
                {
                    var toUpdate = db.Blogs.Single(b => b.Name == "Blog1");
                    toUpdate.Name = "Blog is Updated";
                    var updatedId = toUpdate.Id;
                    var toDelete  = db.Blogs.Single(b => b.Name == "Blog2");
                    toDelete.Name = "Blog to delete";
                    var deletedId = toDelete.Id;

                    db.Entry(toUpdate).State = EntityState.Modified;
                    db.Entry(toDelete).State = EntityState.Deleted;

                    var toAdd = db.Add(
                        new Blog
                    {
                        Name       = "Blog to Insert",
                        George     = true,
                        TheGu      = new Guid("0456AEF1-B7FC-47AA-8102-975D6BA3A9BF"),
                        NotFigTime = new DateTime(1973, 9, 3, 0, 10, 33, 777),
                        ToEat      = 64,
                        OrNothing  = 0.123456789,
                        Fuse       = 777,
                        WayRound   = 9876543210,
                        Away       = 0.12345f,
                        AndChew    = new byte[16]
                    }).Entity;

                    await db.SaveChangesAsync();

                    var addedId = toAdd.Id;
                    Assert.NotEqual(0, addedId);

                    Assert.Equal(EntityState.Unchanged, db.Entry(toUpdate).State);
                    Assert.Equal(EntityState.Unchanged, db.Entry(toAdd).State);
                    Assert.DoesNotContain(toDelete, db.ChangeTracker.Entries().Select(e => e.Entity));

                    Assert.Equal(5, Fixture.TestSqlLoggerFactory.SqlStatements.Count);
                    Assert.Contains("SELECT", Fixture.TestSqlLoggerFactory.SqlStatements[0]);
                    Assert.Contains("SELECT", Fixture.TestSqlLoggerFactory.SqlStatements[1]);
                    Assert.Contains(":p0='" + deletedId, Fixture.TestSqlLoggerFactory.SqlStatements[2]);
                    Assert.Contains("DELETE", Fixture.TestSqlLoggerFactory.SqlStatements[2]);
                    Assert.Contains("UPDATE", Fixture.TestSqlLoggerFactory.SqlStatements[3]);
                    Assert.Contains("INSERT", Fixture.TestSqlLoggerFactory.SqlStatements[4]);

                    var rows = await testDatabase.ExecuteScalarAsync <int>(
                        $@"SELECT Count(*) FROM ""Blog"" WHERE ""Id"" = {updatedId} AND ""Name"" = 'Blog is Updated'");

                    Assert.Equal(1, rows);

                    rows = await testDatabase.ExecuteScalarAsync <int>(
                        $@"SELECT Count(*) FROM ""Blog"" WHERE ""Id"" = {deletedId}");

                    Assert.Equal(0, rows);

                    rows = await testDatabase.ExecuteScalarAsync <int>(
                        $@"SELECT Count(*) FROM ""Blog"" WHERE ""Id"" = {addedId} AND ""Name"" = 'Blog to Insert'");

                    Assert.Equal(1, rows);
                }
            }
        }