// In terms of API design, this method expects tag names in the form of a string array.
        // We shouldn't use TagId because that would only work if the given tag exists in the database.
        // But often, in an application with a good user experience, the user should be able to pick a
        // tag from a drop-down list, or add one at the same time as adding or editing a video. So,
        // we should use tag names to add a new tag to the database. Plus, tag names should be unique,
        // so conceptually, they can be treated as primary keys, but we use an int (TagId) for optimization.
        public static void AddTagsToVideo(int videoId, params string[] tagNames)
        {
            using (var context = new VidzyDbContext())
            {
                var tags = context.Tags.Where(t => tagNames.Contains(t.Name)).ToList();

                foreach (var name in tagNames)
                {
                    if (!tags.Any(t => t.Name == name))
                    {
                        tags.Add(new Tag {
                            Name = name
                        });
                    }
                }

                var video = context.Videos.Include(v => v.Tags).FirstOrDefault(v => v.Id == videoId);

                if (video != null)
                {
                    foreach (var tag in tags)
                    {
                        if (!video.Tags.Any(t => t == tag))
                        {
                            video.Tags.Add(tag);
                        }
                    }
                }

                context.SaveChanges();
            }
        }
        public static void RemoveGenre(int genreId, bool enforceDeletingVideo = false)
        {
            using (var context = new VidzyDbContext())
            {
                var genre = context.Genres.Include(g => g.Videos).FirstOrDefault(g => g.Id == genreId);

                if (genre == null)
                {
                    return;
                }

                if (genre.Videos.Any())
                {
                    if (enforceDeletingVideo)
                    {
                        context.Videos.RemoveRange(genre.Videos);
                    }
                    else
                    {
                        throw new Exception(String.Format("Genre {0} contains some video, and can not be deleted.", genre.Name));
                    }
                }

                context.Genres.Remove(genre);
                context.SaveChanges();
            }
        }
 public static void AddVideo(Video video)
 {
     using (var context = new VidzyDbContext())
     {
         context.Videos.Add(video);
         context.SaveChanges();
     }
 }
        public static void RemoveVideo(int videoId)
        {
            using (var context = new VidzyDbContext())
            {
                var video = context.Videos.FirstOrDefault(v => v.Id == videoId);

                if (video == null)
                {
                    return;
                }

                context.Videos.Remove(video);
                context.SaveChanges();
            }
        }
        public static void RemoveTagsFromVideo(int videoId, params string[] tagNames)
        {
            using (var context = new VidzyDbContext())
            {
                var video = context.Videos.Include(v => v.Tags).Single(v => v.Id == videoId);

                foreach (var tagName in tagNames)
                {
                    // I've encapsulated the concept of removing a tag inside the Video class.
                    // This is the object-oriented way to implement this. The Video class
                    // should be responsible for adding/removing objects to its Tags collection.
                    video.RemoveTag(tagName);
                }

                context.SaveChanges();
            }
        }
        public static void AddTags(params string[] tagNames)
        {
            using (var context = new VidzyDbContext())
            {
                // We load the tags with the given names first, to prevent adding duplicates.
                var tags = context.Tags.Where(t => tagNames.Contains(t.Name)).ToList();

                foreach (var name in tagNames)
                {
                    if (!tags.Any(t => t.Name == name))
                    {
                        context.Tags.Add(new Tag {
                            Name = name
                        });
                    }
                }

                context.SaveChanges();
            }
        }