zoukankan      html  css  js  c++  java
  • 学习ASP.NET Core(03)-数据层逻辑层与模型转换

    上一篇我们使用Code First的方式完成了数据库的建立 ,本章我们来完善一下数据访问层和业务逻辑层部分的内容


    一、IDAL与DAL

    根据依赖倒置原则,细节应该依赖于抽象,我们我们要针对抽象,即面向接口进行编程,其好处是解耦和利于重构

    1、IDAL实现

    1.1、基类接口

    这里添加一个CURD操作的基类接口,名为IBaseRepository,其余每个model都对应一个接口并继承该基类接口。在这之前IDAL层需要添加对Model层的引用。如下:

    using System;
    using System.Linq;
    using System.Threading.Tasks;
    using BlogSystem.Model;
    
    namespace BlogSystem.IDAL
    {
        /// <summary>
        /// 基类接口
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        public interface IBaseRepository<TEntity> where TEntity : BaseEntity
        {
            /// <summary>
            /// 新增数据
            /// </summary>
            /// <param name="entity"></param>
            /// <param name="saved"></param>
            /// <returns></returns>
            Task CreateAsync(TEntity entity, bool saved = true);
    
            /// <summary>
            /// 根据Id删除数据
            /// </summary>
            /// <param name="id"></param>
            /// <param name="saved"></param>
            /// <returns></returns>
            Task RemoveAsync(Guid id, bool saved = true);
    
            /// <summary>
            /// 根据model删除对数据
            /// </summary>
            /// <param name="entity"></param>
            /// <param name="saved"></param>
            /// <returns></returns>
            Task RemoveAsync(TEntity entity, bool saved = true);
    
            /// <summary>
            /// 修改数据
            /// </summary>
            /// <param name="entity"></param>
            /// <param name="saved"></param>
            /// <returns></returns>
            Task EditAsync(TEntity entity, bool saved = true);
    
            /// <summary>
            /// 通过Id查询数据
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            Task<TEntity> GetOneByIdAsync(Guid id);
    
            /// <summary>
            /// 获取所有数据
            /// </summary>
            /// <returns></returns>
            IQueryable<TEntity> GetAll();
    
            /// <summary>
            /// 获取所有数据并排序
            /// </summary>
            /// <returns></returns>
            IQueryable<TEntity> GetAllByOrder(bool asc = true);
    
            /// <summary>
            /// 统一保存方法
            /// </summary>
            /// <returns></returns>
            Task SavedAsync();
    
            /// <summary>
            /// 判断对象是否存在
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            Task<bool> Exists(Guid id);
        }
    }
    

    1.2、其余接口

    其余的每个model也都定义一个接口并继承IBaseRepository,给出一个示例,其余需要一一对应如下:

    using BlogSystem.Model;
    
    namespace BlogSystem.IDAL
    {
        public interface IArticleRepository : IBaseRepository<Article>
        {
        }
    }
    
    


    2、DAL实现

    2.1、基类方法

    首先DAL层需要添加对Model层和DAL层的引用,然后我们在DAL项目下添加一个名为BaseRepository的类,并继承基类接口IBaseRepository,添加泛型约束泛型参数为BlogSystem.Model中的BaseEntity,实现如下:

    using System;
    using System.Linq;
    using System.Threading.Tasks;
    using BlogSystem.IDAL;
    using BlogSystem.Model;
    using Microsoft.EntityFrameworkCore;
    
    namespace BlogSystem.DAL
    {
        /// <summary>
        /// 实现基类接口
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        public class BaseRepository<TEntity> : IBaseRepository<TEntity> where TEntity : BaseEntity, new()
        {
            private readonly BlogSystemContext _context;
    
            public BaseRepository(BlogSystemContext context)
            {
                _context = context;
            }
    
            /// <summary>
            /// 新增数据
            /// </summary>
            /// <param name="entity"></param>
            /// <param name="saved"></param>
            /// <returns></returns>
            public async Task CreateAsync(TEntity entity, bool saved = true)
            {
                _context.Set<TEntity>().Add(entity);
                if (saved) await _context.SaveChangesAsync();
            }
    
            /// <summary>
            /// 根据Id删除数据
            /// </summary>
            /// <param name="id"></param>
            /// <param name="saved"></param>
            /// <returns></returns>
            public async Task RemoveAsync(Guid id, bool saved = true)
            {
                var t = new TEntity() { Id = id };
                _context.Entry(t).State = EntityState.Unchanged;
                t.IsRemoved = true;
                if (saved) await _context.SaveChangesAsync();
            }
    
            /// <summary>
            /// 根据model删除数据
            /// </summary>
            /// <param name="model"></param>
            /// <param name="saved"></param>
            /// <returns></returns>
            public async Task RemoveAsync(TEntity model, bool saved = true)
            {
                await RemoveAsync(model.Id, saved);
            }
    
            /// <summary>
            ///  修改数据
            /// </summary>
            /// <param name="entity"></param>
            /// <param name="saved"></param>
            /// <returns></returns>
            public async Task EditAsync(TEntity entity, bool saved = true)
            {
                _context.Entry(entity).State = EntityState.Modified;
    
                //如果数据没有发生变化
                if (!_context.ChangeTracker.HasChanges()) return;
    
                if (saved) await _context.SaveChangesAsync();
            }
    
            /// <summary>
            /// 通过Id查询数据
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            public async Task<TEntity> GetOneByIdAsync(Guid id)
            {
                return await GetAll().FirstOrDefaultAsync(m => m.Id == id);
            }
    
            /// <summary>
            /// 获取所有数据
            /// </summary>
            /// <returns></returns>
            public IQueryable<TEntity> GetAll()
            {
                return _context.Set<TEntity>().Where(m => !m.IsRemoved).AsNoTracking();
            }
    
            /// <summary>
            /// 获取所有数据并排序
            /// </summary>
            /// <returns></returns>
            public IQueryable<TEntity> GetAllByOrder(bool asc = true)
            {
                var data = GetAll();
                data = asc ? data.OrderBy(m => m.CreateTime) : data.OrderByDescending(m => m.CreateTime);
                return data;
            }
    
            /// <summary>
            /// 统一保存方法
            /// </summary>
            /// <returns></returns>
            public async Task SavedAsync()
            {
                await _context.SaveChangesAsync();
            }
    
            /// <summary>
            /// 确认对象是否存在
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            public async Task<bool> Exists(Guid id)
            {
                return await GetAll().AnyAsync(m => m.Id == id);
            }
        }
    }
    

    2.2、其余方法

    其余IDAL中的接口采用继承的方式实现,给出一个示例,其余同理,如下:

        public class ArticleCommentRepository : BaseRepository<ArticleComment>, IArticleCommentRepository
        {
            public ArticleCommentRepository() : base(new BlogSystemContext(new DbContextOptions<BlogSystemContext>()))
            {
            }
        }
    


    二、模型对象

    1、概念

    在DAL层我们是对数据库的直接操作,面向的也是我们设计的包含属性的model;但在BLL层,面向的是业务逻辑,业务逻辑对应的是用户的操作,在软件的实际使用过程中,用户看到的页面并非对应一个完整的model,页面可能是model的一部分,也有可能由几个model的一部分组合而成的。为了解决这类问题,我们通常使用模型对象

    2、常用的两种模型对象

    1、Dto(Data Transfer Object):又名数据传输对象,常用来定义包含属性的实体类,它只引用基本数据类型,不引用对象类型,且没有行为,它只专注于数据本身,一般用于DAL和BLL之间的数据传输;

    2、ViewModel:又名视图模型,它根据View创建,是View的数据容器,它专注的是View,用来呈现给用户,它由一个或多个Dto的组成;

    3、实际应用

    根据上面的描述,DAL与BLL层的数据交互我们应该使用Dto对象,呈现给页面时需要使用ViewModel对应,但在实际的开发中,Dto与ViewModel重合度很高,所以部分开发者只使用一种,但兼并两类角色。此外,Model与Dto/ViewModel之间的转换,我们可以使用EF的Select方法进行投影解决,或者使用AutoMapper之类的插件。

    三、IBLL与ViewModel

    这里我们根据功能大类,分为用户,文章、分类和评论,所以在IBLL中我们暂时先添加这4个接口, 在这之前需要添加对Model层的引用。根据实体对象部分的讲述,我们在Model层添加一个ViewModels文件夹,里面用来放置ViewModel对象,ViewModel对象属性通常会使用一些特性限制用户的录入。

    1、基类接口

    我们发现可以提取出常用的几个方法,避免重复代码,操作如下:

    using BlogSystem.Model;
    using System;
    using System.Threading.Tasks;
    
    namespace BlogSystem.IBLL
    {
        /// <summary>
        /// 基类服务接口
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        public interface IBaseService<TEntity> where TEntity : BaseEntity
        {
            /// <summary>
            /// 根据Id删除实体
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            Task RemoveAsync(Guid id);
    
            /// <summary>
            /// 删除实体
            /// </summary>
            /// <param name="entity"></param>
            /// <returns></returns>
            Task RemoveAsync(TEntity entity);
    
            /// <summary>
            /// 通过Id查询实体
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            Task<TEntity> GetOneByIdAsync(Guid id);
    
            /// <summary>
            /// 判断实体是否存在
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            Task<bool> ExistsAsync(Guid id);
        }
    }
    

    2、文章接口与ViewModel

    1、在Model层的ViewModel中添加相关的ViewModel,即用户所视内容需要用到的属性

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    
    namespace BlogSystem.Model.ViewModels
    {
        /// <summary>
        /// 创建文章
        /// </summary>
        public class CreateArticleViewModel
        {
            /// <summary>
            /// 创建用户Id
            /// </summary>
            public Guid UserId { get; set; }
    
            /// <summary>
            /// 文章标题
            /// </summary>
            [Required]
            public string Title { get; set; }
    
            /// <summary>
            /// 文章内容
            /// </summary>
            [Required]
            public string Content { get; set; }
    
            /// <summary>
            /// 文章分类
            /// </summary>
            public List<Guid> CategoryIds { get; set; }
        }
    }
    
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    
    namespace BlogSystem.Model.ViewModels
    {
        /// <summary>
        /// 编辑文章
        /// </summary>
        public class EditArticleViewModel
        {
            /// <summary>
            /// 文章Id
            /// </summary>
            public Guid Id { get; set; }
    
            /// <summary>
            /// 文章标题
            /// </summary>
            [Required]
            public string Title { get; set; }
    
            /// <summary>
            /// 文章内容
            /// </summary>
            [Required]
            public string Content { get; set; }
    
            /// <summary>
            /// 文章分类
            /// </summary>
            public List<Guid> CategoryIds { get; set; }
        }
    }
    
    using System;
    
    namespace BlogSystem.Model.ViewModels
    {
        /// <summary>
        /// 文章列表
        /// </summary>
        public class ArticleListViewModel
        {
            /// <summary>
            /// 文章Id
            /// </summary>
            public Guid ArticleId { get; set; }
    
            /// <summary>
            /// 文章标题
            /// </summary>
            public string Title { get; set; }
    
            /// <summary>
            /// 文章内容
            /// </summary>
            public string Content { get; set; }
    
            /// <summary>
            /// 创建时间
            /// </summary>
            public DateTime CreateTime { get; set; }
    
            /// <summary>
            /// 账号
            /// </summary>
            public string Account { get; set; }
    
            /// <summary>
            /// 头像
            /// </summary>
            public string ProfilePhoto { get; set; }
        }
    }
    
    using System;
    using System.Collections.Generic;
    
    namespace BlogSystem.Model.ViewModels
    {
        /// <summary>
        /// 文章详情
        /// </summary>
        public class ArticleDetailsViewModel
        {
            /// <summary>
            /// 文章Id
            /// </summary>
            public Guid Id { get; set; }
    
            /// <summary>
            /// 文章标题
            /// </summary>
            public string Title { get; set; }
    
            /// <summary>
            /// 文章内容
            /// </summary>
            public string Content { get; set; }
    
            /// <summary>
            /// 创建时间
            /// </summary>
            public DateTime CreateTime { get; set; }
    
            /// <summary>
            /// 作者
            /// </summary>
            public string Account { get; set; }
    
            /// <summary>
            /// 头像
            /// </summary>
            public string ProfilePhoto { get; set; }
    
            /// <summary>
            /// 分类Id
            /// </summary>
            public List<Guid> CategoryIds { get; set; }
    
            /// <summary>
            /// 分类名称
            /// </summary>
            public List<string> CategoryNames { get; set; }
    
            /// <summary>
            /// 看好人数
            /// </summary>
            public int GoodCount { get; set; }
            /// <summary>
            /// 不看好人数
            /// </summary>
            public int BadCount { get; set; }
    
        }
    }
    

    2、接口实现:IArticleService继承基类接口,并添加如下方法:

    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using BlogSystem.Model;
    using BlogSystem.Model.ViewModels;
    
    namespace BlogSystem.IBLL
    {
        /// <summary>
        /// 文章接口
        /// </summary>
        public interface IArticleService : IBaseService<Article>
        {
            /// <summary>
            /// 新增文章
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            Task CreateArticleAsync(CreateArticleViewModel model);
    
            /// <summary>
            /// 编辑文章
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            Task EditArticleAsync(EditArticleViewModel model);
    
            /// <summary>
            /// 通过Id获取文章详情
            /// </summary>
            /// <param name="articleId"></param>
            /// <returns></returns>
            Task<ArticleDetailsViewModel> GetArticleDetailsByArticleIdAsync(Guid articleId);
    
            /// <summary>
            /// 通过用户Id获取文章列表
            /// </summary>
            /// <param name="userId"></param>
            /// <returns></returns>
            Task<List<ArticleListViewModel>> GetArticlesByUserIdAsync(Guid userId);
    
            /// <summary>
            /// 通过分类Id获取所有文章
            /// </summary>
            /// <param name="categoryId"></param>
            /// <returns></returns>
            Task<List<ArticleListViewModel>> GetArticlesByCategoryIdAsync(Guid categoryId);
    
            /// <summary>
            /// 通过用户Id获取文章数量
            /// </summary>
            /// <param name="userid"></param>
            /// <returns></returns>
            Task<int> GetArticleCountByUserIdAsync(Guid userid);
    
            /// <summary>
            /// 点赞文章
            /// </summary>
            /// <param name="articleId"></param>
            /// <returns></returns>
            Task AddGoodCount(Guid articleId);
    
            /// <summary>
            /// 点灭文章
            /// </summary>
            /// <param name="articleId"></param>
            /// <returns></returns>
            Task AddBadCount(Guid articleId);
        }
    }
    

    3、分类接口与ViewModel

    1、在Model层的ViewMode文件夹中添加相关的ViewModel

    using System;
    using System.ComponentModel.DataAnnotations;
    
    namespace BlogSystem.Model.ViewModels
    {
        public class CreateOrEditCategoryViewModel
        {
            /// <summary>
            /// 分类名称
            /// </summary>
            [Required]
            public string CategoryName { get; set; }
    
            /// <summary>
            /// 创建用户Id
            /// </summary>
            public Guid UserId { get; set; }
        }
    }
    
    namespace BlogSystem.Model.ViewModels
    {
        public class CategoryListViewModel
        {
            /// <summary>
            /// 分类名称
            /// </summary>
            public string CategoryName { get; set; }
        }
    }
    

    2、分类接口:继承基类接口,并添加如下方法:

    using BlogSystem.Model;
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using BlogSystem.Model.ViewModels;
    
    namespace BlogSystem.IBLL
    {
        /// <summary>
        /// 分类服务接口
        /// </summary>
        public interface ICategoryService : IBaseService<Category>
        {
            /// <summary>
            /// 创建分类
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            Task CreateCategory(CreateOrEditCategoryViewModel model);
    
            /// <summary>
            /// 编辑分类
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            Task EditCategory(CreateOrEditCategoryViewModel model);
    
            /// <summary>
            /// 通过用户Id获取所有分类
            /// </summary>
            /// <param name="userId"></param>
            /// <returns></returns>
            Task<List<CategoryListViewModel>> GetCategoryByUserIdAsync(Guid userId);
        }
    }
    

    4、用户接口与ViewModel

    1、在Model层的ViewModel文件夹中添加相关的ViewModel

    using System;
    using System.ComponentModel.DataAnnotations;
    
    namespace BlogSystem.Model.ViewModels
    {
        /// <summary>
        /// 用户注册
        /// </summary>
        public class RegisterViewModel
        {
            /// <summary>
            /// 账号
            /// </summary>
            [Required]
            public string Account { get; set; }
    
            /// <summary>
            /// 密码
            /// </summary>
            [Required]
            public string Password { get; set; }
    
            /// <summary>
            /// 确认密码
            /// </summary>
            [Required]
            public string RequirePassword { get; set; }
        }
    }
    
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    
    namespace BlogSystem.Model.ViewModels
    {
        /// <summary>
        /// 用户登录
        /// </summary>
        public class LoginViewModel
        {
            /// <summary>
            /// 账号
            /// </summary>
            [Required]
            public string Account { get; set; }
    
            /// <summary>
            /// 密码
            /// </summary>
            [Required]
            public string Password { get; set; }
        }
    }
    
    
    using System;
    using System.ComponentModel.DataAnnotations;
    
    namespace BlogSystem.Model.ViewModels
    {
        /// <summary>
        /// 修改用户密码
        /// </summary>
        public class ChangePwdViewModel
        {
            /// <summary>
            /// 用户Id
            /// </summary>
            public Guid UserId { get; set; }
    
            /// <summary>
            /// 旧密码
            /// </summary>
            [Required]
            public string OldPassword { get; set; }
    
            /// <summary>
            /// 新密码
            /// </summary>
            [Required]
            public string NewPassword { get; set; }
    
            /// <summary>
            /// 确认新密码
            /// </summary>
            [Required]
            public string RequirePassword { get; set; }
        }
    }
    
    using System;
    using System.ComponentModel.DataAnnotations;
    
    namespace BlogSystem.Model.ViewModels
    {
        /// <summary>
        /// 修改用户头像
        /// </summary>
        public class ChangeUserPhotoViewModel
        {
            /// <summary>
            /// 用户Id
            /// </summary>
            public Guid UserId { get; set; }
    
            /// <summary>
            /// 用户头像
            /// </summary>
            [Required]
            public string ProfilePhoto { get; set; }
        }
    }
    
    using System;
    
    namespace BlogSystem.Model.ViewModels
    {
        /// <summary>
        /// 修改用户资料
        /// </summary>
        public class ChangeUserInfoViewModel
        {
            /// <summary>
            /// 用户Id
            /// </summary>
            public Guid UserId { get; set; }
    
            /// <summary>
            /// 账号
            /// </summary>
            public string Account { get; set; }
    
            /// <summary>
            /// 出生日期
            /// </summary>
            public DateTime BirthOfDate { get; set; }
    
            /// <summary>
            /// 性别
            /// </summary>
            public Gender Gender { get; set; }
        }
    }
    
    using System;
    
    namespace BlogSystem.Model.ViewModels
    {
        /// <summary>
        /// 用户详细信息-点击查看主页
        /// </summary>
        public class UserDetailsViewModel
        {
            /// <summary>
            /// 用户Id
            /// </summary>
            public Guid UserId { get; set; }
            /// <summary>
            /// 账号
            /// </summary>
            public string Account { get; set; }
            /// <summary>
            /// 头像
            /// </summary>
            public string ProfilePhoto { get; set; }
            /// <summary>
            /// 年龄
            /// </summary>
            public int Age { get; set; }
            /// <summary>
            /// 性别
            /// </summary>
            public Gender Gender { get; set; }
            /// <summary>
            /// 用户等级
            /// </summary>
            public Level Level { get; set; }
            /// <summary>
            /// 粉丝数
            /// </summary>
            public int FansNum { get; set; }
            /// <summary>
            /// 关注数
            /// </summary>
            public int FocusNum { get; set; }
        }
    }
    
    

    2、用户接口:添加用户方法,如下:

    using System;
    using BlogSystem.Model;
    using BlogSystem.Model.ViewModels;
    using System.Threading.Tasks;
    
    namespace BlogSystem.IBLL
    {
        /// <summary>
        /// 用户服务接口
        /// </summary>
        public interface IUserService : IBaseService<User>
        {
            /// <summary>
            /// 注册
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            Task Register(RegisterViewModel model);
    
            /// <summary>
            /// 登录成功返回userId
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            Task<Guid> Login(LoginViewModel model);
    
            /// <summary>
            /// 修改用户密码
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            Task ChangePassword(ChangePwdViewModel model);
    
            /// <summary>
            /// 修改用户头像
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            Task ChangeUserPhoto(ChangeUserPhotoViewModel model);
    
            /// <summary>
            /// 修改用户信息
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            Task ChangeUserInfo(ChangeUserInfoViewModel model);
    
            /// <summary>
            /// 使用account获取用户信息
            /// </summary>
            /// <param name="account"></param>
            /// <returns></returns>
            Task<UserDetailsViewModel> GetUserInfoByAccount(string account);
        }
    }
    

    5、评论接口与ViewModel

    1、在Model层的ViewModel文件夹中添加相关的ViewModel

    using System;
    
    namespace BlogSystem.Model.ViewModels
    {
        public class CommentListViewModel
        {
            /// <summary>
            /// 文章Id
            /// </summary>
            public Guid ArticleId { get; set; }
    
            /// <summary>
            /// 用户Id
            /// </summary>
            public Guid UserId { get; set; }
    
            /// <summary>
            /// 账号
            /// </summary>
            public string Account { get; set; }
    
            /// <summary>
            /// 评论Id
            /// </summary>
            public Guid CommentId { get; set; }
    
            /// <summary>
            /// 评论内容
            /// </summary>
            public string CommentContent { get; set; }
    
            /// <summary>
            /// 创建时间
            /// </summary>
            public DateTime CreateTime { get; set; }
    
        }
    }
    
    

    2、评论接口:添加接口方法,如下:

    using BlogSystem.Model;
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using BlogSystem.Model.ViewModels;
    
    namespace BlogSystem.IBLL
    {
        /// <summary>
        /// 评论服务接口
        /// </summary>
        public interface ICommentService : IBaseService<ArticleComment>
        {
            /// <summary>
            /// 添加评论
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            Task CreateComment(ArticleComment model);
    
            /// <summary>
            /// 添加回复型评论
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            Task CreateReplyComment(CommentReply model);
    
            /// <summary>
            /// 通过文章Id获取所有评论
            /// </summary>
            /// <param name="articleId"></param>
            /// <returns></returns>
            Task<List<CommentListViewModel>> GetCommentsByArticleIdAsync(Guid articleId);
        }
    }
    

    我们这里暂时只是添加了目前考虑到的一些功能,后续以上的功能可能会进行相关的调整。

    四、BLL实现

    首先,我们需要对BLL层添加对Model,IDAL,IBLL的引用

    1、基类方法

    实现基类方法,如下:

    using System;
    using System.Threading.Tasks;
    using BlogSystem.IBLL;
    using BlogSystem.IDAL;
    using BlogSystem.Model;
    
    namespace BlogSystem.BLL
    {
        /// <summary>
        /// 基类方法
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        public class BaseService<TEntity> : IBaseService<TEntity> where TEntity : BaseEntity, new()
        {
            //通过在子类的构造函数中注入,这里是基类,不用构造函数
            public IBaseRepository<TEntity> BaseRepository;
    
            /// <summary>
            /// 根据Id删除对象
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            public async Task RemoveAsync(Guid id)
            {
                await BaseRepository.RemoveAsync(id);
            }
    
            /// <summary>
            /// 根据实体删除对象
            /// </summary>
            /// <param name="entity"></param>
            /// <returns></returns>
            public async Task RemoveAsync(TEntity entity)
            {
                await BaseRepository.RemoveAsync(entity);
            }
    
            /// <summary>
            /// 查询对象
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            public async Task<TEntity> GetOneByIdAsync(Guid id)
            {
                return await BaseRepository.GetOneByIdAsync(id);
            }
    
            /// <summary>
            /// 判断对象是否存在
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            public async Task<bool> ExistsAsync(Guid id)
            {
                return await BaseRepository.Exists(id);
            }
        }
    }
    

    2、文章方法

    文章方法实现如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using BlogSystem.IBLL;
    using BlogSystem.IDAL;
    using BlogSystem.Model;
    using BlogSystem.Model.ViewModels;
    using Microsoft.EntityFrameworkCore;
    
    namespace BlogSystem.BLL
    {
        /// <summary>
        /// 实现文章接口方法
        /// </summary>
        public class ArticleService : BaseService<Article>, IArticleService
        {
            private readonly IArticleRepository _articleRepository;
            private readonly IArticleInCategoryRepository _articleInCategoryRepository;
            private readonly ICategoryRepository _categoryRepository;
    
            //构造函数注入相关接口
            public ArticleService(IArticleRepository articleRepository, IArticleInCategoryRepository articleInCategoryRepository,
            ICategoryRepository categoryRepository)
            {
                _articleRepository = articleRepository;
                BaseRepository = articleRepository;
                _articleInCategoryRepository = articleInCategoryRepository;
                _categoryRepository = categoryRepository;
            }
    
            /// <summary>
            /// 创建文章
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            public async Task CreateArticleAsync(CreateArticleViewModel model)
            {
                //新增文章
                var article = new Article()
                {
                    UserId = model.UserId,
                    Title = model.Title,
                    Content = model.Content
                };
                await _articleRepository.CreateAsync(article);
    
                //新增文章所属分类
                var articleId = article.Id;
                foreach (var categoryId in model.CategoryIds)
                {
                    await _articleInCategoryRepository.CreateAsync(new ArticleInCategory()
                    {
                        ArticleId = articleId,
                        CategoryId = categoryId
                    }, false);
                }
                await _articleInCategoryRepository.SavedAsync();
            }
    
            /// <summary>
            /// 编辑文章
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            public async Task EditArticleAsync(EditArticleViewModel model)
            {
                //保存文章更新
                var article = await _articleRepository.GetOneByIdAsync(model.Id);
                article.Title = model.Title;
                article.Content = model.Content;
                await _articleRepository.EditAsync(article);
    
                //删除所属分类
                var categoryIds = _articleInCategoryRepository.GetAll();
                foreach (var categoryId in categoryIds)
                {
                    await _articleInCategoryRepository.RemoveAsync(categoryId, false);
                }
                //添加所属分类
                foreach (var categoryId in model.CategoryIds)
                {
                    await _articleInCategoryRepository.CreateAsync(new ArticleInCategory()
                    {
                        ArticleId = model.Id,
                        CategoryId = categoryId
                    }, false);
                }
                //统一保存
                await _articleInCategoryRepository.SavedAsync();
            }
    
            /// <summary>
            /// 获取文章详情
            /// </summary>
            /// <param name="articleId"></param>
            /// <returns></returns>
            public async Task<ArticleDetailsViewModel> GetArticleDetailsByArticleIdAsync(Guid articleId)
            {
                var data = await _articleRepository.GetAll().Include(m => m.User).Where(m => m.Id == articleId)
                    .Select(m => new ArticleDetailsViewModel
                    {
                        Id = m.Id,
                        Title = m.Title,
                        Content = m.Content,
                        CreateTime = m.CreateTime,
                        Account = m.User.Account,
                        ProfilePhoto = m.User.ProfilePhoto,
                        GoodCount = m.GoodCount,
                        BadCount = m.BadCount
                    }).FirstAsync();
                //处理分类
                var categories = await _articleInCategoryRepository.GetAll().Include(m => m.Category)
                    .Where(m => m.ArticleId == data.Id).ToListAsync();
                data.CategoryIds = categories.Select(m => m.CategoryId).ToList();
                data.CategoryNames = categories.Select(m => m.Category.CategoryName).ToList();
                return data;
            }
    
            /// <summary>
            /// 根据用户Id获取文章列表信息
            /// </summary>
            /// <param name="userId"></param>
            /// <returns></returns>
            public async Task<List<ArticleListViewModel>> GetArticlesByUserIdAsync(Guid userId)
            {
                var list = await _articleRepository.GetAllByOrder(false).Include(m => m.User).Where(m => m.UserId == userId)
                    .Select(m => new ArticleListViewModel()
                    {
                        ArticleId = m.Id,
                        Title = m.Title,
                        Content = m.Content,
                        CreateTime = m.CreateTime,
                        Account = m.User.Account,
                        ProfilePhoto = m.User.ProfilePhoto
                    }).ToListAsync();
                return list;
            }
    
            /// <summary>
            /// 通过分类Id获取文章列表
            /// </summary>
            /// <param name="categoryId"></param>
            /// <returns></returns>
            public async Task<List<ArticleListViewModel>> GetArticlesByCategoryIdAsync(Guid categoryId)
            {
                var data = await _categoryRepository.GetOneByIdAsync(categoryId);
                var userId = data.UserId;
                return await GetArticlesByUserIdAsync(userId);
            }
    
            /// <summary>
            /// 获取用户文章数量
            /// </summary>
            /// <param name="userid"></param>
            /// <returns></returns>
            public async Task<int> GetArticleCountByUserIdAsync(Guid userid)
            {
                return await _articleRepository.GetAll().CountAsync(m => m.UserId == userid);
            }
    
            /// <summary>
            /// 看好数量+1
            /// </summary>
            /// <param name="articleId"></param>
            /// <returns></returns>
            public async Task AddGoodCount(Guid articleId)
            {
                var article = await _articleRepository.GetOneByIdAsync(articleId);
                article.GoodCount++;
                await _articleRepository.EditAsync(article);
            }
    
            /// <summary>
            /// 不看好数量+1
            /// </summary>
            /// <param name="articleId"></param>
            /// <returns></returns>
            public async Task AddBadCount(Guid articleId)
            {
                var article = await _articleRepository.GetOneByIdAsync(articleId);
                article.BadCount--;
                await _articleRepository.EditAsync(article);
            }
        }
    }
    

    3、分类方法

    实现分类方法,如下:

    using BlogSystem.IBLL;
    using BlogSystem.IDAL;
    using BlogSystem.Model;
    using BlogSystem.Model.ViewModels;
    using Microsoft.EntityFrameworkCore;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace BlogSystem.BLL
    {
        public class CategoryService : BaseService<Category>, ICategoryService
        {
            private readonly ICategoryRepository _categoryRepository;
    
            public CategoryService(ICategoryRepository categoryRepository)
            {
                _categoryRepository = categoryRepository;
                BaseRepository = categoryRepository;
            }
    
            /// <summary>
            /// 创建分类
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            public async Task CreateCategory(CreateOrEditCategoryViewModel model)
            {
                await _categoryRepository.CreateAsync(new Category()
                {
                    UserId = model.UserId,
                    CategoryName = model.CategoryName
                });
            }
    
            /// <summary>
            /// 编辑分类
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            public async Task EditCategory(CreateOrEditCategoryViewModel model)
            {
                await _categoryRepository.EditAsync(new Category()
                {
                    UserId = model.UserId,
                    CategoryName = model.CategoryName
                });
            }
    
            /// <summary>
            ///  通过用户Id获取所有分类
            /// </summary>
            /// <param name="userId"></param>
            /// <returns></returns>
            public Task<List<CategoryListViewModel>> GetCategoryByUserIdAsync(Guid userId)
            {
                return _categoryRepository.GetAll().Where(m => m.UserId == userId).Select(m => new CategoryListViewModel
                {
                    CategoryName = m.CategoryName
                }).ToListAsync();
            }
        }
    }
    

    4、用户方法

    实现用户方法,如下:

    using BlogSystem.IBLL;
    using BlogSystem.IDAL;
    using BlogSystem.Model;
    using BlogSystem.Model.ViewModels;
    using Microsoft.EntityFrameworkCore;
    using System;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace BlogSystem.BLL
    {
        public class UserService : BaseService<User>, IUserService
        {
            private readonly IUserRepository _userRepository;
    
            public UserService(IUserRepository userRepository)
            {
                _userRepository = userRepository;
                BaseRepository = userRepository;
            }
    
            /// <summary>
            /// 用户注册
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            public async Task Register(RegisterViewModel model)
            {
               //判断账户是否存在
                if (!await _userRepository.GetAll().AnyAsync(m => m.Account == model.Account))
                {
                    await _userRepository.CreateAsync(new User()
                    {
                        Account = model.Account,
                        Password = model.Password
                    });
                }
            }
    
            /// <summary>
            /// 用户登录
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            public async Task<Guid> Login(LoginViewModel model)
            {
                var user = await _userRepository.GetAll().FirstOrDefaultAsync(m => m.Account == model.Account && m.Password == model.Password);
                return user != null ? user.Id : new Guid();
            }
    
            /// <summary>
            /// 修改用户密码
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            public async Task ChangePassword(ChangePwdViewModel model)
            {
                if (await _userRepository.GetAll().AnyAsync(m => m.Id == model.UserId && m.Password == model.OldPassword))
                {
                    var user = await _userRepository.GetAll().FirstOrDefaultAsync(m => m.Id == model.UserId && m.Password == model.OldPassword);
                    user.Password = model.NewPassword;
                    await _userRepository.EditAsync(user);
                }
            }
    
            /// <summary>
            /// 修改用户照片
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            public async Task ChangeUserPhoto(ChangeUserPhotoViewModel model)
            {
                var user = await _userRepository.GetAll().FirstAsync(m => m.Id == model.UserId);
                user.ProfilePhoto = model.ProfilePhoto;
                await _userRepository.EditAsync(user);
            }
    
            /// <summary>
            /// 修改用户信息
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            public async Task ChangeUserInfo(ChangeUserInfoViewModel model)
            {
                var user = await _userRepository.GetAll().FirstAsync(m => m.Id == model.UserId);
                user.Account = model.Account;
                user.Gender = model.Gender;
                user.BirthOfDate = model.BirthOfDate;
                await _userRepository.EditAsync(user);
            }
    
            /// <summary>
            /// 通过账号名称获取用户信息
            /// </summary>
            /// <param name="account"></param>
            /// <returns></returns>
            public async Task<UserDetailsViewModel> GetUserInfoByAccount(string account)
            {
                if (await _userRepository.GetAll().AnyAsync(m => m.Account == account))
                {
                    return await _userRepository.GetAll().Where(m => m.Account == account).Select(m =>
                        new UserDetailsViewModel()
                        {
                            UserId = m.Id,
                            Account = m.Account,
                            ProfilePhoto = m.ProfilePhoto,
                            Age = DateTime.Now.Year - m.BirthOfDate.Year,
                            Gender = m.Gender,
                            Level = m.Level,
                            FansNum = m.FansNum,
                            FocusNum = m.FocusNum
                        }).FirstAsync();
                }
                return new UserDetailsViewModel();
            }
        }
    }
    

    5、评论方法

    实现评论方法,如下:

    using BlogSystem.IBLL;
    using BlogSystem.IDAL;
    using BlogSystem.Model;
    using BlogSystem.Model.ViewModels;
    using Microsoft.EntityFrameworkCore;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace BlogSystem.BLL
    {
        public class CommentService : BaseService<ArticleComment>, ICommentService
        {
            private readonly IArticleCommentRepository _commentRepository;
            private readonly ICommentReplyRepository _commentReplyRepository;
    
            public CommentService(IArticleCommentRepository commentRepository, ICommentReplyRepository commentReplyRepository)
            {
                _commentRepository = commentRepository;
                BaseRepository = commentRepository;
                _commentReplyRepository = commentReplyRepository;
            }
    
            /// <summary>
            /// 添加评论
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            public async Task CreateComment(ArticleComment model)
            {
                await _commentRepository.CreateAsync(model);
            }
    
            /// <summary>
            /// 添加回复型评论
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            public async Task CreateReplyComment(CommentReply model)
            {
                await _commentReplyRepository.CreateAsync(model);
            }
    
            /// <summary>
            /// 根据文章Id获取评论信息
            /// </summary>
            /// <param name="articleId"></param>
            /// <returns></returns>
            public async Task<List<CommentListViewModel>> GetCommentsByArticleIdAsync(Guid articleId)
            {
                return await _commentReplyRepository.GetAllByOrder(false).Where(m => m.ArticleId == articleId)
                    .Include(m => m.ArticleComment).Include(m => m.User).Select(m => new CommentListViewModel()
                    {
                        ArticleId = m.ArticleId,
                        UserId = m.UserId,
                        Account = m.User.Account,
                        CommentId = m.Id,
                        CommentContent = m.Content,
                        CreateTime = m.CreateTime
                    })
                    .ToListAsync();
            }
        }
    }
    
    
    本章只是从整体上将DAL层和BLL的进行了初步的完善,后续会进一步调整,完~

    本人知识点有限,若文中有错误的地方请及时指正,方便大家更好的学习和交流。

    本文的代码结构和方法参考了B站一位UP主的视频内容,地址如下:任生风影

    原创文章声明
  • 相关阅读:
    Spring MVC下拉选项(Select)
    Spring MVC多项单选按钮
    Spring MVC单选按钮
    Spring MVC复选框(多项)
    Spring MVC复选框
    Spring MVC文本域
    Spring MVC密码处理
    Spring MVC页面重定向
    Spring MVC静态页面
    Spring MVC表单处理
  • 原文地址:https://www.cnblogs.com/Jscroop/p/12846644.html
Copyright © 2011-2022 走看看