core3.1创建项目搭建框架
1.先新建一个Core3.1的空项目
Startup文件中需要说明的点:
ConfigureServices方法是用来注入的,Configure方法是用来添加中间件的,中间件类似管道的概念
2.在Startup的ConfigureServices方法里面,在Core3.0中用如下注入MVC
services.AddControllersWithViews();
3.在Startup的Configure方法里面注入相关中间件
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//注册静态文件中间件,不注册就不能访问静态文件
app.UseStaticFiles();
//app.UseHttpsRedirection();注册支持Https的中间件
//app.UseAuthentication();身份验证中间件
//注册路由中间件
app.UseRouting();
//注册端点规则
app.UseEndpoints(endpoints =>
{
//配置路由表形式路由规则
endpoints.MapControllerRoute(
name:"default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
注释掉的 中间件表示在需要用到的时候才加入进来,其他的是常用的。
Net Core 中 在项目下新建文件夹名为 wwwroot 会自动变成一个地球图标 这是Core默认约定的 静态文件夹。
这里顺便说一下app.UseAuthentication是用来干什么的,app.UseAuthentication会启用Authentication中间件,该中间件会根据当前Http请求中的Cookie信息来设置HttpContext.User属性,所以只有在app.UseAuthentication方法之后注册的中间件才能够从HttpContext.User中读取到值,这也是为什么上面强调app.UseAuthentication方法一定要放在下面的app.UseMvc方法前面,因为只有这样ASP.NET Core的MVC中间件中才能读取到HttpContext.User的值。
4.添加实体层Models,这里都是数据库表对应的实体类
添加完之后再把数据库的表实体添加进去,比如这里添加了个用户表实体类
/// <summary>
/// 用户表实体类
/// </summary>
public class SysUser
{
public int Id { get; set; }``
public string UserName { get; set; }
public string Password { get; set; }
}
5.添加数据仓储层Entities,这里用的是EFCore
1.nuget引入 Microsoft.EntityFrameworkCore
2.添加EF上下文类,并且把实体类设置进去
/// <summary>
/// EF操作上下文类
/// </summary>
public class EFContext : DbContext
{
public EFContext(DbContextOptions<EFContext> options) : base(options)
{
}
#region 实体集
public DbSet<SysUser> SysUser { get; set; } //注意 这里名字和实体名字必须一致
#endregion
}
6.配置文件中添加连接字符串(这个配置文件为json格式,以键值对的方式配置)
"ConnectionStrings": {
"conn": "server=.;database=Test;uid=sa;pwd=123" //数据库连接字符串
},
7.把EF上下文注入到Startup的ConfigureServices容器中
1.在web层nuget添加组件
Microsoft.EntityFrameworkCore.SqlServer
2.在Startup的ConfigureServices容器中注入EFContext
//注入EFContext
services.AddDbContext<EFContext>(options =>options.UseSqlServer(Configuration.GetConnectionString("conn")));
3.其中Configuration是读取配置文件的, 需要在Startup中用构造函数注入(Configuration 服务框架已经自动注入到容器了)
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
(到此,已经可以正常连接数据库操作表了,但是一般不会让web层直接用EFContext上下文,我们需要再添加一个服务层Services,我们的业务逻辑就写在这里,有点类似以前的BLL层)
这里的时候可以先在控制器里面演示下 利用EF上下文获取数据库数据,了解下ef的基本使用增删改查
8.添加服务层Services
1.添加一个类库项目Services,然后在里面添加两个文件夹 IService和Service,分别为服务接口和服务实类,之所以加接口,是因为面向接口编程可以降低耦合度,所以Core里面微软默认就推荐这么做
2.接下我们要写每个数据库的表对应的服务层(接口和服务类),由于每个表服务都需要有基本的增删改查分页功能,考虑到这点,我们写一个泛型的类实现增删改查分页等常见操作功能,然后就可以把每个表服务继承它,这样就能省去重复的代码。
新建IBaseService接口
/// <summary>
/// 基接口,操作数据库常用方法:增 删 改 查 分页
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IBaseService<T> where T : class, new()
{
/// <summary>
/// 增(异步)
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
Task<T> AddAsync(T entity);
/// <summary>
/// 增
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
T Add(T entity);
/// <summary>
/// 删除一条数据(异步)
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
Task<bool> DelAsync(T entity);
/// <summary>
/// 删
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
bool Del(T entity);
/// <summary>
/// 删除多条数据(异步)-根据传进来的id数据删除
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
Task<bool> DelByIdsAsync(params int[] ids);
/// <summary>
/// 删除多条数据-根据传进来的id数据删除
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
bool DelByIds(params int[] ids);
/// <summary>
/// 改(异步)
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
Task<bool> EditAsync(T entity);
/// <summary>
/// 改
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
bool Edit(T entity);
/// <summary>
/// 查-获取单条数据(异步)
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
Task<T> GetEntityAsync(System.Linq.Expressions.Expression<Func<T, bool>> whereLambda);
/// <summary>
/// 查-获取单条数据
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
T GetEntity(System.Linq.Expressions.Expression<Func<T, bool>> whereLambda);
/// <summary>
/// 查-获取多条数据,返回list集合(异步)
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
Task<List<T>> GetListEntitiesAsync(System.Linq.Expressions.Expression<Func<T, bool>> whereLambda);
/// <summary>
/// 查-获取多条数据,返回list集合
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
List<T> GetListEntities(System.Linq.Expressions.Expression<Func<T, bool>> whereLambda);
/// <summary>
/// 查询-分页(异步)
/// </summary>
/// <typeparam name="s">排序字段的类型</typeparam>
/// <param name="pageIndex">第几页</param>
/// <param name="pageSize">每页显示多少条</param>
/// <param name="whereLambda">过滤条件lambda</param>
/// <param name="orderbyLambda">排序字段</param>
/// <param name="isAsc">是否升序 true升序 false降序</param>
/// <returns></returns>
Task<List<T>> GetPageListAsync<s>(int pageIndex, int pageSize, System.Linq.Expressions.Expression<Func<T, bool>> whereLambda, System.Linq.Expressions.Expression<Func<T, s>> orderbyLambda, bool isAsc);
/// <summary>
/// 查询-分页
/// </summary>
/// <typeparam name="s">排序字段的类型</typeparam>
/// <param name="pageIndex">第几页</param>
/// <param name="pageSize">每页显示多少条</param>
/// <param name="whereLambda">过滤条件lambda</param>
/// <param name="orderbyLambda">排序字段</param>
/// <param name="isAsc">是否升序 true升序 false降序</param>
/// <param name="totalCount">返回的总记录数</param>
/// <returns>返回实体集合</returns>
List<T> GetPageList<s>(int pageIndex, int pageSize, System.Linq.Expressions.Expression<Func<T, bool>> whereLambda, System.Linq.Expressions.Expression<Func<T, s>> orderbyLambda, bool isAsc, out int totalCount);
/// <summary>
/// 获取总记录数(异步)
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
Task<int> GetTotalCountAsync(Expression<Func<T, bool>> whereLambda);
}
新建BaseService类(即对上面接口的实现)
public class BaseService<T> where T : class, new()
{
public EFContext db;
/// <summary>
/// 增(异步)
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public virtual async Task<T> AddAsync(T entity)
{
db.Set<T>().Add(entity);
await db.SaveChangesAsync();
return entity;
}
/// <summary>
/// 增
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public virtual T Add(T entity)
{
db.Set<T>().Add(entity);
db.SaveChanges();
return entity;
}
/// <summary>
///删除一条实体数据(异步)
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public virtual async Task<bool> DelAsync(T entity)
{
db.Entry(entity).State = EntityState.Deleted;
int i = await db.SaveChangesAsync();
return i > 0;
}
/// <summary>
/// 删除一条实体数据
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public virtual bool Del(T entity)
{
db.Entry(entity).State = EntityState.Deleted;
int i = db.SaveChanges();
return i > 0;
}
/// <summary>
/// 删除多条数据,根据传进来的id数据删除(异步)
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
public virtual async Task<bool> DelByIdsAsync(params int[] ids)
{
foreach (int id in ids)
{
var entity = db.Set<T>().Find(id);//如果实体已经在内存中则直接从内存中拿,否则才查询数据库
db.Set<T>().Remove(entity);
}
int i = await db.SaveChangesAsync();
return i > 0;
}
/// <summary>
/// 删除多条数据,根据传进来的id数据删除
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
public virtual bool DelByIds(params int[] ids)
{
foreach (int id in ids)
{
var entity = db.Set<T>().Find(id);//如果实体已经在内存中则直接从内存中拿,否则才查询数据库
db.Set<T>().Remove(entity);
}
int i = db.SaveChanges();
return i > 0;
}
/// <summary>
/// 改(异步)
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public virtual async Task<bool> EditAsync(T entity)
{
db.Entry(entity).State = EntityState.Modified;
int i = await db.SaveChangesAsync();
return i > 0;
}
/// <summary>
/// 改
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public virtual bool Edit(T entity)
{
db.Entry(entity).State = EntityState.Modified;
int i = db.SaveChanges();
return i > 0;
}
/// <summary>
/// 查-获取单条数据(异步)
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
public virtual async Task<T> GetEntityAsync(System.Linq.Expressions.Expression<Func<T, bool>> whereLambda)
{
return await db.Set<T>().Where(whereLambda).FirstOrDefaultAsync();
}
/// <summary>
/// 查-获取单条数据
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
public virtual T GetEntity(System.Linq.Expressions.Expression<Func<T, bool>> whereLambda)
{
return db.Set<T>().Where(whereLambda).FirstOrDefault();
}
/// <summary>
/// 查-获取多条数据,返回list集合(异步)
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
public virtual async Task<List<T>> GetListEntitiesAsync(System.Linq.Expressions.Expression<Func<T, bool>> whereLambda)
{
return await db.Set<T>().Where(whereLambda).ToListAsync();
}
/// <summary>
/// 查-获取多条数据,返回list集合
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
public virtual List<T> GetListEntities(System.Linq.Expressions.Expression<Func<T, bool>> whereLambda)
{
return db.Set<T>().Where(whereLambda).ToList();
}
/// <summary>
/// 查询-分页(异步)
/// </summary>
/// <typeparam name="s"></typeparam>
/// <param name="pageIndex">第几页</param>
/// <param name="pageSize">每页多少条</param>
/// <param name="whereLambda">过滤数据的Lambda表达式</param>
/// <param name="orderbyLambda">按照哪个排序</param>
/// <param name="isAsc">是否升序排序:true升序、false降序</param>
/// <returns></returns>
public async Task<List<T>> GetPageListAsync<s>(int pageIndex, int pageSize,
System.Linq.Expressions.Expression<Func<T, bool>> whereLambda,
System.Linq.Expressions.Expression<Func<T, s>> orderbyLambda, bool isAsc)
{
List<T> list = null;
if (isAsc)//升序
{
list = await db.Set<T>().Where(whereLambda).OrderBy(orderbyLambda).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync();
}
else//降序
{
list = await db.Set<T>().Where(whereLambda).OrderByDescending(orderbyLambda).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync();
}
return list;
}
/// <summary>
/// 查询-分页
/// </summary>
/// <typeparam name="s"></typeparam>
/// <param name="pageIndex"></param>
/// <param name="pageSize"></param>
/// <param name="whereLambda"></param>
/// <param name="orderbyLambda"></param>
/// <param name="isAsc"></param>
/// <returns></returns>
public List<T> GetPageList<s>(int pageIndex, int pageSize,
System.Linq.Expressions.Expression<Func<T, bool>> whereLambda,
System.Linq.Expressions.Expression<Func<T, s>> orderbyLambda, bool isAsc, out int totalCount)
{
List<T> list = null;
totalCount = db.Set<T>().Where(whereLambda).Count();
if (isAsc)//升序
{
list = db.Set<T>().Where(whereLambda).OrderBy(orderbyLambda).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
}
else//降序
{
list = db.Set<T>().Where(whereLambda).OrderByDescending(orderbyLambda).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
}
return list;
}
/// <summary>
/// 获取总条数(异步)
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
public async Task<int> GetTotalCountAsync(Expression<Func<T, bool>> whereLambda)
{
return await db.Set<T>().Where(whereLambda).CountAsync();
}
}
3.添加SysUser表的服务类和接口
接口
/// <summary>
/// 用户表服务接口
/// </summary>
public interface ISysUserService:IBaseService<SysUser>
{
}
服务类
/// <summary>
/// SysUser表服务类
/// </summary>
public class SysUserService:BaseService<SysUser>,ISysUserService
{
/// <summary>
/// 构造函数注入EFContext上下文
/// </summary>
/// <param name="eFContext"></param>
public SysUserService(EFContext eFContext)
{
db = eFContext;
}
}
9.回到web层,在Startup中把SysUser表服务类和接口注入到容器中
//添加SysUser表服务
services.AddScoped<ISysUserService, SysUserService>();
10.接下来就可以在控制器中通过构造函数注入的方式来调用SysUser表服务啦