写在前面
上篇文章简单介绍了项目的结构,这篇文章将实现用户的注册。当然关于漂亮的ui,这在追后再去添加了,先将功能实现。也许代码中有不合适的地方,也只有在之后慢慢去优化了。
系列文章
[EF]vs15+ef6+mysql code first方式
[实战]MVC5+EF6+MySql企业网盘实战(1)
[实战]MVC5+EF6+MySql企业网盘实战(2)——用户注册
实现
Model层
UserInfo实体模型


using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.ComponentModel.DataAnnotations; using Wolfy.NetDisk.Utilities;namespace Wolfy.NetDisk.Model {/// <summary>/// 用户信息类/// </summary>public class UserInfo{/// <summary>/// 编号/// </summary> [Key]public int Id { set; get; }/// <summary>/// 用户头像地址/// </summary>[StringLength(512)][Display(Name = "头像")]public string Header { set; get; }/// <summary>/// 姓名/// </summary>[MaxLength(64, ErrorMessage = "网名长度不得超过32个字符")][Required(ErrorMessage = "请填写您的名称")][Display(Name = "姓名")]public string Name { set; get; }/// <summary>/// 网名/// </summary>[MaxLength(64, ErrorMessage = "网名长度不得超过32个字符")][Required(ErrorMessage = "请填写您的网名")][Display(Name = "网名")]public string DisplayName { set; get; }/// <summary>/// 邮箱/// </summary>[RegularExpression(@"^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$", ErrorMessage = "请输入正确的邮箱地址")][MaxLength(2048, ErrorMessage = "网名长度不得超过2048个字符")][Required][Display(Name = "邮箱")]public string Email { set; get; }/// <summary>/// 婚姻情况/// </summary>[Display(Name = "婚姻状况")]public MarriageType Marriage { set; get; }/// <summary>/// 政治面貌/// </summary>[Display(Name = "政治面貌")]public PoliticalStatus PoliticalStatus { set; get; }/// <summary>/// 学历/// </summary>[Display(Name = "学历")]public XueliType Xueli { set; get; }/// <summary>/// 职位/// </summary>[MaxLength(128)][Display(Name = "职位")]public string Position { set; get; }/// <summary>/// 电话/// </summary>[MaxLength(32)][Display(Name = "电话")]public string Tel { set; get; }/// <summary>/// 密码/// </summary>[StringLength(32, ErrorMessage = "密码长度不得超多32位")][Required][Display(Name = "密码")]public string Pwd { set; get; }/// <summary>/// 生日/// </summary>[Display(Name = "生日")]public DateTime Birthday { set; get; } = DateTime.Now;/// <summary>/// 性别/// </summary>[Display(Name = "性别")]public GenderType Gender { set; get; }/// <summary>/// 住址/// </summary>[MaxLength(32)][Display(Name = "地址")]public string Address { set; get; }/// <summary>/// 籍贯/// </summary>[MaxLength(32)][Display(Name = "籍贯")]public string Hometown { set; get; }/// <summary>/// 公司/// </summary>[StringLength(512, ErrorMessage = "公司名称超过了512字符")][Display(Name = "公司名称")]public string Company { set; get; }/// <summary>/// 所属部门id/// </summary>[Display(Name = "部门")]public int DepartmentId { set; get; }/// <summary>/// 添加时间/// </summary>[Display(Name = "日期")]public DateTime Dt { set; get; } = DateTime.Now;} }
IDAL层
添加泛型接口IBaseRepository<TEntity>,存放一些常用的操作,增删改查等。


/// <summary>/// 仓储基类泛型接口/// </summary>/// <typeparam name="TEntity"></typeparam>public interface IBaseRepository<TEntity> : IDisposable{/// <summary>/// 添加实体/// </summary>/// <param name="entity"></param>/// <returns></returns> TEntity Add(TEntity entity);/// <summary>/// 计数/// </summary>/// <param name="where"></param>/// <returns></returns>int Count(Expression<Func<TEntity, bool>> where);/// <summary>/// 更新/// </summary>/// <param name="entity"></param>/// <returns></returns> TEntity Update(TEntity entity);bool Delete(TEntity entity);/// <summary>/// 是否存在/// </summary>/// <param name="where"></param>/// <returns></returns>bool Exist(Expression<Func<TEntity, bool>> where);/// <summary>/// 条件查询/// </summary>/// <param name="where"></param>/// <returns></returns>TEntity Find(Expression<Func<TEntity, bool>> where);/// <summary>/// 查询集合/// </summary>/// <param name="where"></param>/// <returns></returns>IQueryable<TEntity> FindAll(Expression<Func<TEntity, bool>> where);/// <summary>/// 条件查询/// </summary>/// <typeparam name="SEntity"></typeparam>/// <param name="where"></param>/// <param name="isAsc">是否升序</param>/// <param name="orderlanbda">排序表达式</param>/// <returns></returns>IQueryable<TEntity> FindAll<SEntity>(Expression<Func<TEntity, bool>> where, bool isAsc, Expression<Func<TEntity, SEntity>> orderlanbda);/// <summary>/// 分页查询/// </summary>/// <typeparam name="SEntity"></typeparam>/// <param name="pageIndex"></param>/// <param name="pageSize"></param>/// <param name="totalRecord"></param>/// <param name="where"></param>/// <param name="isAsc"></param>/// <param name="orderLambda"></param>/// <returns></returns>IQueryable<TEntity> FindPaged<SEntity>(int pageIndex, int pageSize, out int totalRecord, Expression<Func<TEntity, bool>> where, bool isAsc, Expression<Func<TEntity, SEntity>> orderLambda);/// <summary>/// 保存/// </summary>/// <returns></returns>int SaveChanges();}
IUserInfoRepository:UserInfo操作接口。


/// <summary>/// 用户信息仓储接口/// </summary>public interface IUserInfoRepository : IBaseRepository<UserInfo>{}
DAL层
添加数据库上下文NetDiskContext类。关于ef6+mysql code first的具体使用可以参考前面的文章。


/// <summary>/// 数据库上下文/// </summary>public class NetDiskContext : DbContext{/// <summary>/// name:数据库连接字符串/// </summary>public NetDiskContext(): base("name=NetDiskContext"){}public DbSet<UserInfo> UserInfos { set; get; }//public DbSet<Department> Deparments { set; get; }//public DbSet<Model.NetDisk> NetDisks { set; get; }}
ContextFactory:用来获取数据上下文的工厂,代码如下,第一次使用ef,也不知道有没有更好的实现方式,先这样实现吧,以后发现更好的方式,再进行优化。


/// <summary>/// 数据上下文工厂类/// </summary>public static class ContextFactory{/// <summary>/// 获取数据库上下文/// </summary>/// <returns></returns>public static DbContext GetDbContext(){NetDiskContext _netDiskContext = CallContext.GetData("NetDiskContext") as NetDiskContext;if (_netDiskContext == null){_netDiskContext = new NetDiskContext();IDatabaseInitializer<NetDiskContext> dbInitializer = null;if (_netDiskContext.Database.Exists()){//如果数据库已经存在dbInitializer = new DropCreateDatabaseIfModelChanges<NetDiskContext>();}else{//总是先删除然后再创建dbInitializer = new DropCreateDatabaseAlways<NetDiskContext>();}dbInitializer.InitializeDatabase(_netDiskContext);CallContext.SetData("NetDiskContext", _netDiskContext);return _netDiskContext;}return _netDiskContext;}}
BaseRepository:泛型基类,实现接口IBaseRepository


using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; using Wolfy.NetDisk.IDAL;namespace Wolfy.NetDisk.DAL {/// <summary>/// 仓储基类/// </summary>public class BaseRepository<TEntity> : IBaseRepository<TEntity> where TEntity : class{protected NetDiskContext netDiskContext = ContextFactory.GetDbContext() as NetDiskContext;public TEntity Add(TEntity entity){netDiskContext.Entry<TEntity>(entity).State = System.Data.Entity.EntityState.Added;return entity;}public int Count(Expression<Func<TEntity, bool>> where){return netDiskContext.Set<TEntity>().Count(where);}public bool Delete(TEntity entity){netDiskContext.Entry<TEntity>(entity).State = System.Data.Entity.EntityState.Deleted;return this.SaveChanges() > 0;}public void Dispose(){if (netDiskContext != null){netDiskContext.Dispose();GC.SuppressFinalize(netDiskContext);}}public bool Exist(Expression<Func<TEntity, bool>> where){return netDiskContext.Set<TEntity>().Any(where);}public TEntity Find(Expression<Func<TEntity, bool>> where){return netDiskContext.Set<TEntity>().FirstOrDefault(where);}public IQueryable<TEntity> FindAll(Expression<Func<TEntity, bool>> where){return netDiskContext.Set<TEntity>().Where(where);}public IQueryable<TEntity> FindAll<SEntity>(Expression<Func<TEntity, bool>> where, bool isAsc, Expression<Func<TEntity, SEntity>> orderlanbda){var lst = netDiskContext.Set<TEntity>().Where<TEntity>(where);if (!isAsc){lst = lst.OrderByDescending<TEntity, SEntity>(orderlanbda);}return lst;}public IQueryable<TEntity> FindPaged<SEntity>(int pageIndex, int pageSize, out int totalRecord, Expression<Func<TEntity, bool>> where, bool isAsc, Expression<Func<TEntity, SEntity>> orderLambda){var lst = netDiskContext.Set<TEntity>().Where<TEntity>(where);totalRecord = lst.Count();if (!isAsc){lst = lst.OrderByDescending<TEntity, SEntity>(orderLambda);}return lst.Skip<TEntity>((pageIndex - 1) * pageIndex).Take(pageSize);}public int SaveChanges(){return netDiskContext.SaveChanges();}public TEntity Update(TEntity entity){TEntity tentity = netDiskContext.Set<TEntity>().Attach(entity);netDiskContext.Entry<TEntity>(entity).State = System.Data.Entity.EntityState.Modified;return tentity;}} }


/// <summary>/// 用户数据操作dal层 /// </summary>public class UserInfoRepository:BaseRepository<UserInfo>, IUserInfoRepository{}
仓储工厂,用来获取具体的仓储接口。


using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Wolfy.NetDisk.IDAL; using Wolfy.NetDisk.Model;namespace Wolfy.NetDisk.DAL {/// <summary>/// 仓储工厂/// </summary>public static class RepositoryFactory{public static IUserInfoRepository UserInfoRepository { get { return new UserInfoRepository(); } }} }
IBLL层


using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks;namespace Wolfy.NetDisk.IBLL {public interface IBaseServiceRepository<TEntity>{/// <summary>/// 添加实体/// </summary>/// <param name="entity"></param>/// <returns></returns> TEntity Add(TEntity entity);/// <summary>/// 计数/// </summary>/// <param name="where"></param>/// <returns></returns>int Count(Expression<Func<TEntity, bool>> where);/// <summary>/// 更新/// </summary>/// <param name="entity"></param>/// <returns></returns> TEntity Update(TEntity entity);bool Delete(TEntity entity);/// <summary>/// 是否存在/// </summary>/// <param name="where"></param>/// <returns></returns>bool Exist(Expression<Func<TEntity, bool>> where);/// <summary>/// 条件查询/// </summary>/// <param name="where"></param>/// <returns></returns>TEntity Find(Expression<Func<TEntity, bool>> where);/// <summary>/// 查询集合/// </summary>/// <param name="where"></param>/// <returns></returns>IQueryable<TEntity> FindAll(Expression<Func<TEntity, bool>> where);/// <summary>/// 条件查询/// </summary>/// <typeparam name="SEntity"></typeparam>/// <param name="where"></param>/// <param name="isAsc">是否升序</param>/// <param name="orderlanbda">排序表达式</param>/// <returns></returns>IQueryable<TEntity> FindAll<SEntity>(Expression<Func<TEntity, bool>> where, bool isAsc, Expression<Func<TEntity, SEntity>> orderlanbda);/// <summary>/// 分页查询/// </summary>/// <typeparam name="SEntity"></typeparam>/// <param name="pageIndex"></param>/// <param name="pageSize"></param>/// <param name="totalRecord"></param>/// <param name="where"></param>/// <param name="isAsc"></param>/// <param name="orderLambda"></param>/// <returns></returns>IQueryable<TEntity> FindPaged<SEntity>(int pageIndex, int pageSize, out int totalRecord, Expression<Func<TEntity, bool>> where, bool isAsc, Expression<Func<TEntity, SEntity>> orderLambda);int SaveChanges();} }


using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Wolfy.NetDisk.Model;namespace Wolfy.NetDisk.IBLL {public interface IUserInfoServiceRepository:IBaseServiceRepository<UserInfo>{} }
BLL层


using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; using Wolfy.NetDisk.IBLL; using Wolfy.NetDisk.IDAL;namespace Wolfy.NetDisk.BLL {public class BaseServiceRepository<TEntity> : IBaseServiceRepository<TEntity> where TEntity : class,new(){protected IBaseRepository<TEntity> currentRepository { set; get; }public BaseServiceRepository(IBaseRepository<TEntity> currentRepository){this.currentRepository = currentRepository;}public TEntity Add(TEntity entity){return currentRepository.Add(entity);}public int Count(Expression<Func<TEntity, bool>> where){return currentRepository.Count(where);}public bool Delete(TEntity entity){return currentRepository.Delete(entity);}public bool Exist(Expression<Func<TEntity, bool>> where){return currentRepository.Exist(where);}public TEntity Find(Expression<Func<TEntity, bool>> where){return currentRepository.Find(where);}public IQueryable<TEntity> FindAll(Expression<Func<TEntity, bool>> where){return currentRepository.FindAll(where);}public IQueryable<TEntity> FindAll<SEntity>(Expression<Func<TEntity, bool>> where, bool isAsc, Expression<Func<TEntity, SEntity>> orderlanbda){return currentRepository.FindAll<SEntity>(where, isAsc, orderlanbda);}public IQueryable<TEntity> FindPaged<SEntity>(int pageIndex, int pageSize, out int totalRecord, Expression<Func<TEntity, bool>> where, bool isAsc, Expression<Func<TEntity, SEntity>> orderLambda){return currentRepository.FindPaged<SEntity>(pageIndex, pageSize, out totalRecord, where, isAsc, orderLambda);}public int SaveChanges(){return currentRepository.SaveChanges();}public TEntity Update(TEntity entity){return currentRepository.Update(entity);}} }


using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Wolfy.NetDisk.Model; using Wolfy.NetDisk.DAL; using Wolfy.NetDisk.IBLL; using Wolfy.NetDisk.IDAL;namespace Wolfy.NetDisk.BLL {public class UserInfoServiceRepository : BaseServiceRepository<UserInfo>, IUserInfoServiceRepository{/// <summary>/// 构造函数,通过仓储工厂调用dal中的具体的仓储/// </summary>/// <param name="currentRepository"></param>public UserInfoServiceRepository(): base(RepositoryFactory.UserInfoRepository){}} }
UI层
添加UserInfo控制器


using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Web; using System.Web.Mvc; using Wolfy.NetDisk.Model; using Wolfy.NetDisk.IBLL; using Wolfy.NetDisk.BLL; namespace Wolfy.NetDisk.Site.Controllers {public class UserInfoController : AsyncController{private IUserInfoServiceRepository _userInfoServiceRepository = new UserInfoServiceRepository();/// <summary>/// 用户信息列表/// </summary>/// <returns></returns>public ActionResult Users(){var users = _userInfoServiceRepository.FindAll(x => x.DisplayName != "");return View(users);}[HttpGet]public ActionResult Register(){return View();}[HttpPost]public ActionResult Register(UserInfo userInfo){if (ModelState.IsValid){_userInfoServiceRepository.Add(userInfo);_userInfoServiceRepository.SaveChanges();}return RedirectToAction("Users");}} }
添加视图
先不管界面的美与丑,先试下能否正确的添加数据。如果成功下一步,再进行美化。
总结
下面将完善注册的过程,用户名是否存在验证,密码加密,验证码等操作。