Inheritance: DbContext, IGenericServicesDbContext
        public void Check10ValidatePostOk()
        {
            using (var db = new SampleWebAppDb())
            {
                //SETUP
                var snap = new DbSnapShot(db);
                var existingTag = db.Tags.First();
                var existingBlogger = db.Blogs.First();

                //ATTEMPT
                var newPost = new Post()
                {
                    Blogger = existingBlogger,
                    Title = "Test post",
                    Content = "Nothing special",
                    Tags = new[] { existingTag }
                };
                db.Posts.Add(newPost);
                var status = db.SaveChangesWithChecking();

                //VERIFY
                status.IsValid.ShouldEqual(true, status.Errors);
                snap.CheckSnapShot(db,1,1);
            }
        }
        public void Check02DatabaseDataLinksOk()
        {
            using (var db = new SampleWebAppDb())
            {
                //SETUP
                DataLayerInitialise.InitialiseThis();
                var filepath = TestFileHelpers.GetTestFileFilePath("DbContentSimple.xml");

                //ATTEMPT
                DataLayerInitialise.ResetDatabaseToTestData(db, filepath);

                //VERIFY
                var allPosts = db.Posts.Include(x => x.Blogger).Include(x => x.Tags).ToList();
                allPosts[0].Blogger.Name.ShouldEqual("Fred Bloggs");
                string.Join(",", allPosts[0].Tags.Select(x => x.Slug)).ShouldEqual("ugly,bad");
                allPosts[1].Blogger.Name.ShouldEqual("Jon Smith");
                string.Join(",", allPosts[1].Tags.Select(x => x.Slug)).ShouldEqual("good,ugly");
                allPosts[2].Blogger.Name.ShouldEqual("Jon Smith");
                string.Join(",", allPosts[2].Tags.Select(x => x.Slug)).ShouldEqual("bad");

                db.PostTagGrades.Count().ShouldEqual(2);
                db.PostTagGrades.ToList().All( x => x.PostId == allPosts[0].PostId).ShouldEqual(true);
                string.Join(",", db.PostTagGrades.Include(x => x.TagPart).Select(x => x.TagPart.Slug)).ShouldEqual("bad,ugly");
            }
        }
 public DbSnapShot(SampleWebAppDb db)
 {
     NumBlogs = db.Blogs.Count();
     NumPostTagLinks = db.Database.SqlQuery<int>("SELECT COUNT(*) FROM dbo.TagPosts").First();
     NumPosts = db.Posts.Count();
     NumTags = db.Tags.Count();
     NumPostTagGrades = db.PostTagGrades.Count();
 }
 public void SetUpFixture()
 {
     using (var db = new SampleWebAppDb())
     {
         DataLayerInitialise.InitialiseThis();
         var filepath = TestFileHelpers.GetTestFileFilePath("DbContentSimple.xml");
         DataLayerInitialise.ResetDatabaseToTestData(db, filepath);
     }
 }
        static void Main(string[] args)
        {
            using (var db = new SampleWebAppDb())
            {
                var firstId = db.Posts.First().PostId;
                RunCommand1(db);
                RunCommand2(db);
            }

        }
        public void CheckSnapShot(SampleWebAppDb db, int postsChange = 0, int postTagLinkChange = 0, int blogsChange = 0, int tagsChange = 0, int postTagGradesChange = 0)
        {
            var newSnap = new DbSnapShot(db);

            newSnap.NumPosts.ShouldEqual( NumPosts + postsChange, "posts wrong");
            newSnap.NumPostTagLinks.ShouldEqual(NumPostTagLinks + postTagLinkChange, "posttaglinks wrong");
            newSnap.NumBlogs.ShouldEqual(NumBlogs + blogsChange, "blogs wrong");
            newSnap.NumTags.ShouldEqual(NumTags + tagsChange, "tags wrong");
            newSnap.NumPostTagGrades.ShouldEqual(NumPostTagGrades + postTagGradesChange, "postTagGrades wrong");
        }
        public void Check01ReadBlogsNoPostsOk()
        {
            using (var db = new SampleWebAppDb())
            {
                //SETUP

                //ATTEMPT
                var blogs = db.Blogs.ToList();

                //VERIFY
                blogs.Count.ShouldEqual(2);
                blogs.All( x => x.Posts == null).ShouldEqual(true);
            }
        }
        public void Check01CreateSetupFlowOk()
        {
            using (var db = new SampleWebAppDb())
            {
                //SETUP
                var service = new CreateSetupService<Tag, SimpleTagDto>(db);

                //ATTEMPT
                var dto = service.GetDto();

                //VERIFY
                dto.FunctionsCalledCommaDelimited.ShouldEqual("SetupSecondaryData");
            }
        }
        public void Test02NoSingleExceptionSetBad()
        {
            using (var db = new SampleWebAppDb())
            {
                //SETUP
                GenericServicesConfig.RealiseSingleExceptionMethod = null;

                //ATTEMPT
                var ex = Assert.Throws<InvalidOperationException>(() => db.Posts.RealiseSingleWithErrorChecking());

                //VERIFY
                ex.Message.ShouldEqual("Sequence contains more than one element");
            }
        }
        public void Test01NoSingleExceptionSetOk()
        {
            using (var db = new SampleWebAppDb())
            {
                //SETUP
                var id = db.Posts.First().PostId;
                GenericServicesConfig.RealiseSingleExceptionMethod = null;

                //ATTEMPT
                var status = db.Posts.Where(x => x.PostId == id).RealiseSingleWithErrorChecking();

                //VERIFY
                status.IsValid.ShouldEqual(true, status.Errors);
            }
        }
        public void FixtureSetup()
        {
            //This remembers the SqlErrorTextDict
            _rememberDefaultSqlErrorTextDict =
                GenericServicesConfig.SqlErrorDict.Select(x => new KeyValuePair<int, string>(x.Key, x.Value))
                    .ToList();
            GenericServicesConfig.ClearSqlHandlerDict();

            using (var db = new SampleWebAppDb())
            {
                DataLayerInitialise.InitialiseThis();
                var filepath = TestFileHelpers.GetTestFileFilePath("DbContentSimple.xml");
                DataLayerInitialise.ResetDatabaseToTestData(db, filepath);
            }
        }
        public void Check02FillComputedNPostOk()
        {
            using (var db = new SampleWebAppDb())
            {
                //SETUP
                const int numToCreate = 20;
                var snap = new DbSnapShot();        //empty

                //ATTEMPT
                db.FillComputedNPost(numToCreate);

                //VERIFY
                snap.CheckSnapShot(db, numToCreate, numToCreate, 2, 2);
                (db.Posts.Max(x => x.PostId) - db.Posts.Min(x => x.PostId)).ShouldEqual(numToCreate - 1);       //check numbers are consecutive
            }
        }
        public async void Perf10CreateSetupServiceOk()
        {

            using (var db = new SampleWebAppDb())
            {
                //SETUP
                var service = new CreateSetupServiceAsync<Post, DetailPostDtoAsync>(db);

                //ATTEMPT
                var dto = await service.GetDtoAsync();
                dto.LogSpecificName("End");

                //VERIFY
                foreach (var log in dto.LogOfCalls) { Console.WriteLine(log); }
            }
        }
        public void Check05ListEfDirectOk()
        {
            using (var db = new SampleWebAppDb())
            {
                //SETUP
                var timer = new Stopwatch();
                timer.Start();

                //ATTEMPT
                db.ListEfDirect<Post>(0);
                timer.Stop();

                //VERIFY
                Console.WriteLine("Ef operation took {0} ms",timer.ElapsedMilliseconds);
            }
        }
        public static void ResetDatabaseToTestData(SampleWebAppDb context, string filepathOfXmlFile)
        {
            context.Posts.RemoveRange( context.Posts);
            context.Tags.RemoveRange( context.Tags);
            context.Blogs.RemoveRange( context.Blogs);
            context.PostTagGrades.RemoveRange(context.PostTagGrades);
            context.PostLinks.RemoveRange(context.PostLinks);
            context.SaveChanges();

            var loader = new LoadDbDataFromXml(filepathOfXmlFile);

            context.Blogs.AddRange(loader.Bloggers);                //note: The order things appear in the database are not obvious
            //have to add these by hand
            context.PostTagGrades.AddRange(loader.PostTagGrades);
            context.SaveChanges();
        }
        public async void Check06ListEfViaDtoOk()
        {
            using (var db = new SampleWebAppDb())
            {
                //SETUP
                var timer = new Stopwatch();
                timer.Start();

                //ATTEMPT
                await db.ListPostEfViaDtoAsync(0);
                timer.Stop();

                //VERIFY
                Console.WriteLine("Ef operation took {0} ms", timer.ElapsedMilliseconds);
            }
        }
        public void Check01DetailFlowOk()
        {
            using (var db = new SampleWebAppDb())
            {
                //SETUP
                var service = new DetailService<Tag, SimpleTagDto>(db);
                var firstTag = db.Tags.First();

                //ATTEMPT
                var status = service.GetDetailUsingWhere(x => x.TagId == firstTag.TagId);

                //VERIFY
                status.IsValid.ShouldEqual(true, status.Errors);
                status.Result.FunctionsCalledCommaDelimited.ShouldEqual("DetailDtoFromDataIn");
            }
        }
        public async void Check01UpdateSetupFlowOk()
        {
            using (var db = new SampleWebAppDb())
            {
                //SETUP
                var service = new UpdateSetupServiceAsync<Tag, SimpleTagDtoAsync>(db);
                var firstTag = db.Tags.First();

                //ATTEMPT
                var status = await service.GetOriginalAsync(firstTag.TagId);

                //VERIFY
                status.IsValid.ShouldEqual(true, status.Errors);
                status.Result.FunctionsCalledCommaDelimited.ShouldEqual("DetailDtoFromDataInAsync,SetupSecondaryDataAsync");
            }
        }
        public static void ResetDatabaseToTestData(SampleWebAppDb context, string filepathOfXmlFile)
        {
            context.Posts.RemoveRange(context.Posts);
            context.Tags.RemoveRange(context.Tags);
            context.Blogs.RemoveRange(context.Blogs);
            context.PostTagGrades.RemoveRange(context.PostTagGrades);
            context.PostLinks.RemoveRange(context.PostLinks);
            context.SaveChanges();

            var loader = new LoadDbDataFromXml(filepathOfXmlFile);

            context.Blogs.AddRange(loader.Bloggers);                //note: The order things appear in the database are not obvious
            //have to add these by hand
            context.PostTagGrades.AddRange(loader.PostTagGrades);
            context.SaveChanges();
        }
        public async Task Check03DetailDirectPostOk()
        {
            using (var db = new SampleWebAppDb())
            {
                //SETUP
                var service = new DetailServiceAsync(db);
                var firstPost = db.Posts.First();

                //ATTEMPT
                var status = await service.GetDetailAsync<Post>(firstPost.PostId);

                //VERIFY
                status.IsValid.ShouldEqual(true, status.Errors);
                status.Result.PostId.ShouldEqual(firstPost.PostId);
                status.Result.Title.ShouldEqual(firstPost.Title);
            }
        }
        public void Check01ValidateTagOk()
        {
            using (var db = new SampleWebAppDb())
            {
                //SETUP
                var snap = new DbSnapShot(db);

                //ATTEMPT
                var dupTag = new Tag { Name = "non-duplicate slug", Slug = Guid.NewGuid().ToString("N") };
                db.Tags.Add(dupTag);
                var status = db.SaveChangesWithChecking();

                //VERIFY
                status.IsValid.ShouldEqual(true, status.Errors);
                snap.CheckSnapShot(db, 0,0,0,1);
            }
        }
        public void Test02ListDirectPostOk()
        {
            using (var db = new SampleWebAppDb())
            {
                //SETUP
                var service = new ListService<Post>(db);
                var firstPost = db.Posts.Include(x => x.Blogger).First();

                //ATTEMPT
                var list = service.GetAll().Include(x => x.Blogger).ToList();
                
                //VERIFY
                list.Count().ShouldEqual(3);
                list.First().Title.ShouldEqual(firstPost.Title);
                list.First().Blogger.Name.ShouldEqual(firstPost.Blogger.Name);
                list.First().Tags.ShouldEqual(null);
            }
        }
        public void Check01PostTagGradeDeleteOk()
        {
            using (var db = new SampleWebAppDb())
            {
                //SETUP
                var snap = new DbSnapShot(db);
                var service = new DeleteService(db);
                var firstPtgUntracked = db.PostTagGrades.AsNoTracking().First();

                //ATTEMPT
                var status = service.Delete<PostTagGrade>(firstPtgUntracked.PostId, firstPtgUntracked.TagId);

                //VERIFY
                status.IsValid.ShouldEqual(true, status.Errors);
                snap.CheckSnapShot(db, 0,0,0,0,-1);

            }
        }
        public void Check02ValidateTagError()
        {
            using (var db = new SampleWebAppDb())
            {
                //SETUP
                var existingTag = db.Tags.First();

                //ATTEMPT
                var dupTag = new Tag {Name = "duplicate slug", Slug = existingTag.Slug};
                db.Tags.Add(dupTag);
                var status = db.SaveChangesWithChecking();

                //VERIFY
                status.IsValid.ShouldEqual(false);
                status.Errors.Count.ShouldEqual(1);
                status.Errors[0].ErrorMessage.ShouldEqual("The Slug on tag 'duplicate slug' must be unique.");
            }
        }
        public void Check01ListGradesOk()
        {
            using (var db = new SampleWebAppDb())
            {
                //SETUP
                var service = new ListService<PostTagGrade, SimplePostTagGradeDto>(db);
                var firstGrade = db.PostTagGrades.Include(x => x.TagPart).Include(x => x.PostPart).First();

                //ATTEMPT
                var list = service.GetAll().ToList();

                //VERIFY
                list.Count().ShouldEqual(2);
                list.First().PostPartTitle.ShouldEqual(firstGrade.PostPart.Title);
                list.First().TagPartName.ShouldEqual(firstGrade.TagPart.Name);

            }
        }
        public async void Check02UpdateFailOk()
        {
            using (var db = new SampleWebAppDb())
            {
                //SETUP
                var service = new UpdateServiceAsync<Tag, SimpleTagDtoAsync>(db);
                var dto = new SimpleTagDtoAsync();
                dto.SetSupportedFunctions(CrudFunctions.None);

                //ATTEMPT
                var status = await service.UpdateAsync(dto);

                //VERIFY
                status.IsValid.ShouldEqual(false);
                status.Errors.Count.ShouldEqual(1);
                status.Errors[0].ErrorMessage.ShouldEndWith("is not supported in this mode.");
                dto.FunctionsCalledCommaDelimited.ShouldEqual("");
            }
        }
        public async Task Check04DetailDirectDtoOk()
        {
            using (var db = new SampleWebAppDb())
            {
                //SETUP
                var service = new DetailServiceAsync(db);
                var firstPost = db.Posts.Include(x => x.Tags).AsNoTracking().First();

                //ATTEMPT
                var status = await service.GetDetailAsync<SimplePostDtoAsync>(firstPost.PostId);

                //VERIFY
                status.IsValid.ShouldEqual(true, status.Errors);
                status.Result.PostId.ShouldEqual(firstPost.PostId);
                status.Result.BloggerName.ShouldEqual(firstPost.Blogger.Name);
                status.Result.Title.ShouldEqual(firstPost.Title);
                CollectionAssert.AreEqual(firstPost.Tags.Select(x => x.TagId), status.Result.Tags.Select(x => x.TagId));
            }
        }
        public void Check02ListBlogsCheckIncludesPostsOk()
        {
            using (var db = new SampleWebAppDb())
            {
                //SETUP
                var service = new ListService<Blog, SimpleBlogWithPostsDto>(db);

                //ATTEMPT
                var list = service.GetAll().ToList();

                //VERIFY
                list.Count().ShouldEqual(2);
                var firstBlog = db.Blogs.Include(x => x.Posts).AsNoTracking().First();
                list.First().Name.ShouldEqual(firstBlog.Name);
                list.First().EmailAddress.ShouldEqual(firstBlog.EmailAddress);
                list.First().Posts.ShouldNotEqualNull();
                CollectionAssert.AreEquivalent(firstBlog.Posts.Select(x => x.PostId), list.First().Posts.Select(x => x.PostId));
            }
        }
        public void Perf05UpdateSetupOk()
        {
            int postId;
            using (var db = new SampleWebAppDb())
                postId = db.Posts.Include(x => x.Tags).AsNoTracking().First().PostId;

            using (var db = new SampleWebAppDb())
            {
                //SETUP
                var service = new UpdateSetupService<Post, SimplePostDto>(db);

                //ATTEMPT
                var status = service.GetOriginal(postId);
                status.Result.LogSpecificName("End");

                //VERIFY
                foreach (var log in status.Result.LogOfCalls) { Console.WriteLine(log); }
            }
        }
        public void Check01DatabaseResetOk()
        {
            using (var db = new SampleWebAppDb())
            {
                //SETUP
                DataLayerInitialise.InitialiseThis();
                var filepath = TestFileHelpers.GetTestFileFilePath("DbContentSimple.xml");

                //ATTEMPT
                DataLayerInitialise.ResetDatabaseToTestData(db, filepath);

                //VERIFY
                db.Blogs.Count().ShouldEqual(2);
                db.Posts.Count().ShouldEqual(3);
                db.Tags.Count().ShouldEqual(3);
                db.Database.SqlQuery<int>("SELECT COUNT(*) FROM dbo.TagPosts").First().ShouldEqual(5);
                db.PostTagGrades.Count().ShouldEqual(2);
            }
        }
        public async void Perf03DetailPostOk()
        {
            int postId;
            using (var db = new SampleWebAppDb())
                postId = db.Posts.Include(x => x.Tags).AsNoTracking().First().PostId;

            using (var db = new SampleWebAppDb())
            {
                //SETUP
                var service = new DetailServiceAsync<Post, DetailPostDtoAsync>(db);

                //ATTEMPT
                var status = await service.GetDetailAsync(postId);
                status.Result.LogSpecificName("End");

                //VERIFY
                foreach (var log in status.Result.LogOfCalls) { Console.WriteLine(log); }
            }
        }