/// <summary> /// Seed settings, user, post, category and tags. /// </summary> /// <param name="db"></param> private void Seed(FanDbContext db) { db.Set <Meta>().AddRange(GetSettings()); // settings db.Users.Add(GetUser()); // user db.Set <Post>().Add(GetPostWith1Category2Tags()); // post with category and tags db.SaveChanges(); }
/// <summary> /// Deletes a <see cref="Category"/> by id and re-categorize its posts to the given /// default category id. /// </summary> /// <remarks> /// Since <see cref="Post.CategoryId"/> is nullable, there is no Cascade Delete between /// Post and Category, which happens to be what we want. User can choose to delete a /// category and we should delete all posts associated with that category, instead we /// apply the default category on these posts. /// /// The defaultCategoryId is BlogSettings DefaultCategoryId, I choose to have it pass in /// from BLL for convenience instead of querying Meta for it. /// </remarks> public async Task DeleteAsync(int id, int defaultCategoryId) { if (id == defaultCategoryId) { return; } // remove it var category = await _entities.SingleAsync(c => c.Id == id); _db.Remove(category); // update its posts to default category var posts = _db.Set <Post>().Where(p => p.CategoryId == id); foreach (var post in posts) { post.CategoryId = defaultCategoryId; } await _db.SaveChangesAsync(); }
/// <summary> /// Returns all tags or empty list if no tags found. The returned list is ordered by /// <see cref="Tag.Count"/> desc and then by <see cref="Tag.Title"/>. /// </summary> public async Task <List <Tag> > GetListAsync() { return(await(from t in _entities select new Tag { Id = t.Id, Title = t.Title, Slug = t.Slug, Color = t.Color, Description = t.Description, Count = (from p in _db.Set <Post>() from pt in p.PostTags where pt.TagId == t.Id && p.Status == EPostStatus.Published select pt).Count(), }).OrderByDescending(t => t.Count).ThenBy(t => t.Title).ToListAsync()); }
/// <summary> /// Creates a <see cref="Post"/>. /// </summary> /// <param name="post">The post to create.</param> /// <param name="tagTitles">A list of tag titles associated with the post.</param> /// <returns> /// The inserted post with id. /// </returns> public async Task <Post> CreateAsync(Post post, int?categoryId, string categoryTitle, IEnumerable <string> tagTitles) { // Category if (!categoryTitle.IsNullOrEmpty()) { // from metaweblog with a cat inputted post.Category = _db.Set <Category>().First(c => c.Title.Equals(categoryTitle, StringComparison.CurrentCultureIgnoreCase)); } else { post.CategoryId = categoryId.HasValue ? // from browser categoryId : // from metaweblog with no cat inputted Convert.ToInt32(_db.Set <Meta>().First(m => m.Key.Equals("blogsettings.defaultcategoryid")).Value); } // PostTags if (!tagTitles.IsNullOrEmpty()) { // make sure list has no empty strings and only unique values tagTitles = tagTitles.Where(s => !string.IsNullOrWhiteSpace(s)).Distinct(); var tags = _db.Set <Tag>(); // all tags foreach (var title in tagTitles) { // lookup the tag (any new tag is already created prior) var tag = tags.First(t => t.Title.Equals(title, StringComparison.CurrentCultureIgnoreCase)); post.PostTags.Add(new PostTag { Post = post, Tag = tag }); } } await _entities.AddAsync(post); await _db.SaveChangesAsync(); return(post); }
/// <summary> /// Creates a <see cref="Post"/>. /// </summary> /// <param name="post">The post to create.</param> /// <param name="categoryTitle">The category title is available when called from metaweblog.</param> /// <param name="tagTitles">A list of tag titles associated with the post.</param> /// <returns> /// The inserted post with id. /// </returns> public async Task <Post> CreateAsync(Post post, string categoryTitle, IEnumerable <string> tagTitles) { // Category if (!categoryTitle.IsNullOrEmpty()) { // cat title present, olw and setup post.Category = _db.Set <Category>().First(c => c.Title.ToUpper() == categoryTitle.ToUpper()); } else if (!post.CategoryId.HasValue) // from browser CategoryId will have value { // from metaweblog with no cat inputted, give it the default cat id post.CategoryId = Convert.ToInt32(_db.Set <Meta>().First(m => m.Key.Equals("blogsettings.defaultcategoryid")).Value); } // PostTags if (!tagTitles.IsNullOrEmpty()) { // make sure list has no empty strings and only unique values tagTitles = tagTitles.Where(s => !string.IsNullOrWhiteSpace(s)).Distinct(); var tags = _db.Set <Tag>(); // all tags foreach (var title in tagTitles) { // lookup the tag (any new tag is already created prior) var tag = tags.First(t => t.Title.ToUpper() == title.ToUpper()); post.PostTags.Add(new PostTag { Post = post, Tag = tag }); } } await _entities.AddAsync(post); await _db.SaveChangesAsync(); return(post); }
/// <summary> /// Returns a list of posts and total post count by query or empty list if no posts found. /// </summary> /// <param name="query"></param> /// <returns></returns> public async Task <(List <Post> posts, int totalCount)> GetListAsync(PostListQuery query) { List <Post> posts = null; int skip = (query.PageIndex - 1) * query.PageSize; int take = query.PageSize; IQueryable <Post> q = _entities.Include(p => p.User).Include(p => p.Category).Include(p => p.PostTags).ThenInclude(p => p.Tag); switch (query.QueryType) { case EPostListQueryType.BlogPosts: q = q.Where(p => p.Status == EPostStatus.Published && p.Type == EPostType.BlogPost); posts = await q.OrderByDescending(p => p.CreatedOn).Skip(skip).Take(take).ToListAsync(); break; case EPostListQueryType.BlogDrafts: q = q.Where(p => p.Status == EPostStatus.Draft && p.Type == EPostType.BlogPost); posts = await q.OrderByDescending(p => p.UpdatedOn).ToListAsync(); break; case EPostListQueryType.BlogPostsByCategory: var cat = await _db.Set <Category>().FirstAsync(t => t.Slug.Equals(query.CategorySlug, StringComparison.CurrentCultureIgnoreCase)); q = q.Where(p => p.CategoryId == cat.Id && p.Status == EPostStatus.Published && p.Type == EPostType.BlogPost); posts = await q.OrderByDescending(p => p.CreatedOn).Skip(skip).Take(take).ToListAsync(); break; case EPostListQueryType.BlogPostsByTag: var tag = await _db.Set <Tag>().FirstAsync(t => t.Slug.Equals(query.TagSlug, StringComparison.CurrentCultureIgnoreCase)); q = from p in q from pt in p.PostTags where p.Id == pt.PostId && pt.TagId == tag.Id && p.Status == EPostStatus.Published && p.Type == EPostType.BlogPost select p; posts = await q.OrderByDescending(p => p.CreatedOn).Skip(skip).Take(take).ToListAsync(); break; case EPostListQueryType.BlogPostsArchive: q = (query.Month.HasValue && query.Month > 0) ? q.Where(p => p.CreatedOn.Year == query.Year && p.CreatedOn.Month == query.Month && p.Status == EPostStatus.Published && p.Type == EPostType.BlogPost) : q.Where(p => p.CreatedOn.Year == query.Year && p.Status == EPostStatus.Published && p.Type == EPostType.BlogPost); posts = await q.OrderByDescending(p => p.CreatedOn).ToListAsync(); break; case EPostListQueryType.BlogPostsByNumber: q = q.Where(p => p.Type == EPostType.BlogPost); posts = await q.OrderByDescending(p => p.CreatedOn).Take(take).ToListAsync(); break; case EPostListQueryType.RootPages: q = _entities.Where(p => p.RootId == 0 && p.Status == EPostStatus.Published && p.Type == EPostType.Page); posts = await q.OrderByDescending(p => p.CreatedOn).ToListAsync(); break; case EPostListQueryType.ChildPagesForRoot: q = _entities.Where(p => p.RootId == query.RootId && p.Status == EPostStatus.Published && p.Type == EPostType.Page); posts = await q.OrderByDescending(p => p.CreatedOn).ToListAsync(); break; case EPostListQueryType.PageDrafts: q = _entities.Where(p => p.Status == EPostStatus.Draft && p.Type == EPostType.Page); posts = await q.OrderByDescending(p => p.UpdatedOn).ToListAsync(); break; case EPostListQueryType.PagesByNumber: q = _entities.Where(p => p.Type == EPostType.Page); posts = await q.OrderByDescending(p => p.CreatedOn).Take(take).ToListAsync(); break; } int postCount = await q.CountAsync(); return(posts : posts, totalCount : postCount); }
/// <summary> /// Seeds 1 blog post associated with 1 category and 2 tags. /// </summary> /// <param name="db"></param> protected void SeedTestPost() { _db.Users.Add(Actor.User); _db.Set <Post>().Add(GetPost()); _db.SaveChanges(); }