.netCore+Vue 搭建的简捷开发框架 (2)--仓储层实现和EFCore 的使用
书接上文,继续搭建我们基于.netCore 的开发框架。首先是我们的项目分层结构。
这个分层结构,是参考张老师的分层结构,但是实际项目中,我没有去实现仓储模型。因为我使用的是EFCore ,最近也一直在想,EFCore 在我们的架构体系中到底扮演着什么样的角色??
当然,实现仓储层,也有他的好处,如果真的以后要更换ORM框架的时候,不用去更改服务层逻辑,不用直接在仓储里面做更改就可以了。但是对于小项目,可能运行个十年都不会换数据库,不会换ORM的项目,仓储层的意义在哪?
希望对此有自己想法的朋友一起讨论。在本系列里,我将保留仓储层。
上面的分层结构,很容易就搭建好了,但是基于.NetCore 的项目,可能最主要的一点就是如何利用好DI,怎么来实现依赖注入。
依照上图中的依赖关系,我们以此构建自己相应层级中的内容。
分别在IRepository和Repository项目下,新建Base文件夹,并分别建立IBaseRepository和BaseRepository
具体代码如下:
IBaseRepository.cs:
using Sincere.Core.Model;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks; namespace Sincere.Core.IRepository.Base
{
public interface IBaseRepository<TEntity> where TEntity : class
{
Task<int> Execute(string sql, List<SqlParameter> parms, CommandType cmdType = CommandType.Text);
Task<List<TEntity>> Query(string sql, List<SqlParameter> parms, CommandType cmdType = CommandType.Text);
Task<bool> Insert(TEntity model);
Task<bool> InsertRange(List<TEntity> datas); Task<int> Del(TEntity model); Task<int> DelBy(Expression<Func<TEntity, bool>> delWhere); Task<int> Modify(TEntity model); Task<int> Modify(TEntity model, params string[] propertyNames); Task<int> ModifyBy(TEntity model, Expression<Func<TEntity, bool>> whereLambda, params string[] modifiedPropertyNames); Task<List<TEntity>> GetList(); Task<List<TEntity>> GetListBy(Expression<Func<TEntity, bool>> whereLambda); Task<TEntity> GetModelById(Expression<Func<TEntity, bool>> whereLambda); Task<List<TEntity>> GetListBy<TKey>(Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, TKey>> orderLambda, bool isAsc = true); Task<List<TEntity>> GetListBy<TKey>(int top, Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, TKey>> orderLambda, bool isAsc = true); Task<List<TEntity>> GetListBy<TKey1, TKey2>(Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, TKey1>> orderLambda1, Expression<Func<TEntity, TKey2>> orderLambda2, bool isAsc1 = true, bool isAsc2 = true); Task<List<TEntity>> GetListBy<TKey1, TKey2>(int top, Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, TKey1>> orderLambda1, Expression<Func<TEntity, TKey2>> orderLambda2, bool isAsc1 = true, bool isAsc2 = true); Task<List<TEntity>> GetPagedList<TKey>(int pageIndex, int pageSize, Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, TKey>> orderByLambda, bool isAsc = true); Task<PageModel<TEntity>> GetPagedList<TKey>(Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, TKey>> orderByLambda, bool isAsc = true, int pageIndex = , int pageSize = ); void RollBackChanges(); }
}
BaseRepository.cs:
using Microsoft.EntityFrameworkCore;
using Sincere.Core.IRepository.Base;
using Sincere.Core.Model;
using Sincere.Core.Model.Models;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks; namespace Sincere.Core.Repository.Base
{
public class BaseRepository<TEntity> : IBaseRepository<TEntity> where TEntity : class, new()
{
private BaseCoreContext _db;
private readonly DbSet<TEntity> _dbSet; internal BaseCoreContext Db
{
get { return _db; }
private set { _db = value; }
}
public BaseRepository(IBaseContext mydbcontext)
{
this._db = mydbcontext as BaseCoreContext;
this._dbSet = _db.Set<TEntity>();
} #region INSERT /// <summary>
/// 新增 实体
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
//public async Task<bool> Insert(TEntity model, bool isSaveChanges = false)
public async Task<bool> Insert(TEntity model)
{
_db.Set<TEntity>().Add(model);
//if (isSaveChanges)
//{
return await _db.SaveChangesAsync() > ;
//}
//else
//{
// return false;
//} } /// <summary>
/// 普通批量插入
/// </summary>
/// <param name="datas"></param>
public async Task<bool> InsertRange(List<TEntity> datas)
{
await _db.Set<TEntity>().AddRangeAsync(datas);
return await _db.SaveChangesAsync() == datas.Count;
} #endregion INSERT #region Delete #region 2.0 根据id删除 + int Del(T model)
/// <summary>
/// 2.0 根据id删除
/// </summary>
/// <param name="model">必须包含要删除id的对象</param>
/// <returns></returns>
public async Task<int> Del(TEntity model)
{
_db.Set<TEntity>().Attach(model);
_db.Set<TEntity>().Remove(model);
return await _db.SaveChangesAsync();
}
#endregion #region 2.1 根据条件删除 + int DelBy(Expression<Func<T, bool>> delWhere)
/// <summary>
/// 2.1 根据条件删除
/// </summary>
/// <param name="delWhere"></param>
/// <returns>返回受影响的行数</returns>
public async Task<int> DelBy(Expression<Func<TEntity, bool>> delWhere)
{
//2.1.1 查询要删除的数据
List<TEntity> listDeleting = _db.Set<TEntity>().Where(delWhere).ToList();
//2.1.2 将要删除的数据 用删除方法添加到 EF 容器中
listDeleting.ForEach(u =>
{
_db.Set<TEntity>().Attach(u); //先附加到EF 容器
_db.Set<TEntity>().Remove(u); //标识为删除状态
});
//2.1.3 一次性生成sql语句 到数据库执行删除
return await _db.SaveChangesAsync();
}
#endregion #endregion #region UPDATE #region 3.0 修改实体 + int Modify(T model)
/// <summary>
/// 修改实体
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public async Task<int> Modify(TEntity model)
{
//EntityEntry entry = _db.Entry<TEntity>(model);
_db.Set<TEntity>().Update(model);
return await _db.SaveChangesAsync();
}
#endregion #region 3.1 修改实体,可修改指定属性 + int Modify(T model, params string[] propertyNames)
/// <summary>
/// 3.1 修改实体,可修改指定属性
/// </summary>
/// <param name="model"></param>
/// <param name="propertyName"></param>
/// <returns></returns>
public async Task<int> Modify(TEntity model, params string[] propertyNames)
{
//3.1.1 将对象添加到EF中
EntityEntry entry = _db.Entry<TEntity>(model);
//3.1.2 先设置对象的包装状态为 Unchanged
entry.State = EntityState.Unchanged;
//3.1.3 循环被修改的属性名数组
foreach (string propertyName in propertyNames)
{
//将每个被修改的属性的状态设置为已修改状态;这样在后面生成的修改语句时,就只为标识为已修改的属性更新
entry.Property(propertyName).IsModified = true;
}
return await _db.SaveChangesAsync();
}
#endregion #region 3.2 批量修改 + int ModifyBy(T model, Expression<Func<T, bool>> whereLambda, params string[] modifiedPropertyNames)
/// <summary>
/// 3.2 批量修改
/// </summary>
/// <param name="model"></param>
/// <param name="whereLambda"></param>
/// <param name="modifiedPropertyNames"></param>
/// <returns></returns>
public async Task<int> ModifyBy(TEntity model, Expression<Func<TEntity, bool>> whereLambda, params string[] modifiedPropertyNames)
{
//3.2.1 查询要修改的数据
List<TEntity> listModifing = _db.Set<TEntity>().Where(whereLambda).ToList();
//3.2.2 获取实体类类型对象
Type t = typeof(TEntity);
//3.2.3 获取实体类所有的公共属性
List<PropertyInfo> propertyInfos = t.GetProperties(BindingFlags.Instance | BindingFlags.Public).ToList();
//3.2.4 创建实体属性字典集合
Dictionary<string, PropertyInfo> dicPropertys = new Dictionary<string, PropertyInfo>();
//3.2.5 将实体属性中要修改的属性名 添加到字典集合中 键:属性名 值:属性对象
propertyInfos.ForEach(p =>
{
if (modifiedPropertyNames.Contains(p.Name))
{
dicPropertys.Add(p.Name, p);
}
});
//3.2.6 循环要修改的属性名
foreach (string propertyName in modifiedPropertyNames)
{
//判断要修改的属性名是否在实体类的属性集合中存在
if (dicPropertys.ContainsKey(propertyName))
{
//如果存在,则取出要修改的属性对象
PropertyInfo proInfo = dicPropertys[propertyName];
//取出要修改的值
object newValue = proInfo.GetValue(model, null);
//批量设置要修改对象的属性
foreach (TEntity item in listModifing)
{
//为要修改的对象的要修改的属性设置新的值
proInfo.SetValue(item, newValue, null);
}
}
}
//一次性生成sql语句 到数据库执行
return await _db.SaveChangesAsync();
}
#endregion #endregion UPDATE #region SELECT #region 5.0 根据条件查询 + List<TEntity> GetListBy(Expression<Func<T, bool>> whereLambda)
/// <summary>
/// 5.0 根据条件查询
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
public async Task<List<TEntity>> GetListBy(Expression<Func<TEntity, bool>> whereLambda)
{
return await _db.Set<TEntity>().Where(whereLambda).AsNoTracking().ToListAsync();
} public async Task<TEntity> GetModelById(Expression<Func<TEntity, bool>> whereLambda)
{
return await _db.Set<TEntity>().Where(whereLambda).AsNoTracking().FirstOrDefaultAsync();
}
public async Task<List<TEntity>> GetList()
{
return await _db.Set<TEntity>().AsNoTracking().ToListAsync();
}
#endregion #region 5.1 根据条件查询,并排序 + List<TEntity> GetListBy<TKey>(Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> orderLambda, bool isAsc = true)
/// <summary>
/// 5.1 根据条件查询,并排序
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="whereLambda"></param>
/// <param name="orderLambda"></param>
/// <param name="isAsc"></param>
/// <returns></returns>
public async Task<List<TEntity>> GetListBy<TKey>(Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, TKey>> orderLambda, bool isAsc = true)
{
if (isAsc)
{
return await _db.Set<TEntity>().Where(whereLambda).OrderBy(orderLambda).AsNoTracking().ToListAsync();
}
else
{
return await _db.Set<TEntity>().Where(whereLambda).OrderByDescending(orderLambda).AsNoTracking().ToListAsync();
}
}
#endregion #region 5.2 根据条件查询Top多少个,并排序 + List<TEntity> GetListBy<TKey>(int top, Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> orderLambda, bool isAsc = true)
/// <summary>
/// 5.2 根据条件查询Top多少个,并排序
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="top"></param>
/// <param name="whereLambda"></param>
/// <param name="orderLambda"></param>
/// <param name="isAsc"></param>
/// <returns></returns>
public async Task<List<TEntity>> GetListBy<TKey>(int top, Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, TKey>> orderLambda, bool isAsc = true)
{
if (isAsc)
{
return await _db.Set<TEntity>().Where(whereLambda).OrderBy(orderLambda).Take(top).AsNoTracking().ToListAsync();
}
else
{
return await _db.Set<TEntity>().Where(whereLambda).OrderByDescending(orderLambda).Take(top).AsNoTracking().ToListAsync();
}
}
#endregion #region 5.3 根据条件排序查询 双排序 + List<TEntity> GetListBy<TKey1, TKey2>(Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey1>> orderLambda1, Expression<Func<T, TKey2>> orderLambda2, bool isAsc1 = true, bool isAsc2 = true)
/// <summary>
/// 5.3 根据条件排序查询 双排序
/// </summary>
/// <typeparam name="TKey1"></typeparam>
/// <typeparam name="TKey2"></typeparam>
/// <param name="whereLambda"></param>
/// <param name="orderLambda1"></param>
/// <param name="orderLambda2"></param>
/// <param name="isAsc1"></param>
/// <param name="isAsc2"></param>
/// <returns></returns>
public async Task<List<TEntity>> GetListBy<TKey1, TKey2>(Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, TKey1>> orderLambda1, Expression<Func<TEntity, TKey2>> orderLambda2, bool isAsc1 = true, bool isAsc2 = true)
{
if (isAsc1)
{
if (isAsc2)
{
return await _db.Set<TEntity>().Where(whereLambda).OrderBy(orderLambda1).ThenBy(orderLambda2).AsNoTracking().ToListAsync();
}
else
{
return await _db.Set<TEntity>().Where(whereLambda).OrderBy(orderLambda1).ThenByDescending(orderLambda2).AsNoTracking().ToListAsync();
}
}
else
{
if (isAsc2)
{
return await _db.Set<TEntity>().Where(whereLambda).OrderByDescending(orderLambda1).ThenBy(orderLambda2).AsNoTracking().ToListAsync();
}
else
{
return await _db.Set<TEntity>().Where(whereLambda).OrderByDescending(orderLambda1).ThenByDescending(orderLambda2).AsNoTracking().ToListAsync();
}
}
}
#endregion #region 5.3 根据条件排序查询Top个数 双排序 + List<TEntity> GetListBy<TKey1, TKey2>(int top, Expression<Func<T, bool>> whereLambda, System.Linq.Expressions.Expression<Func<T, TKey1>> orderLambda1, Expression<Func<T, TKey2>> orderLambda2, bool isAsc1 = true, bool isAsc2 = true)
/// <summary>
/// 5.3 根据条件排序查询Top个数 双排序
/// </summary>
/// <typeparam name="TKey1"></typeparam>
/// <typeparam name="TKey2"></typeparam>
/// <param name="top"></param>
/// <param name="whereLambda"></param>
/// <param name="orderLambda1"></param>
/// <param name="orderLambda2"></param>
/// <param name="isAsc1"></param>
/// <param name="isAsc2"></param>
/// <returns></returns>
public async Task<List<TEntity>> GetListBy<TKey1, TKey2>(int top, Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, TKey1>> orderLambda1, Expression<Func<TEntity, TKey2>> orderLambda2, bool isAsc1 = true, bool isAsc2 = true)
{
if (isAsc1)
{
if (isAsc2)
{
return await _db.Set<TEntity>().Where(whereLambda).OrderBy(orderLambda1).ThenBy(orderLambda2).Take(top).AsNoTracking().ToListAsync();
}
else
{
return await _db.Set<TEntity>().Where(whereLambda).OrderBy(orderLambda1).ThenByDescending(orderLambda2).Take(top).AsNoTracking().ToListAsync();
}
}
else
{
if (isAsc2)
{
return await _db.Set<TEntity>().Where(whereLambda).OrderByDescending(orderLambda1).ThenBy(orderLambda2).Take(top).AsNoTracking().ToListAsync();
}
else
{
return await _db.Set<TEntity>().Where(whereLambda).OrderByDescending(orderLambda1).ThenByDescending(orderLambda2).Take(top).AsNoTracking().ToListAsync();
}
}
}
#endregion #endregion SELECT #region 分页 #region 6.0 分页查询 + List<T> GetPagedList<TKey>
/// <summary>
/// 分页查询 + List<TEntity> GetPagedList
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="pageIndex">页码</param>
/// <param name="pageSize">页容量</param>
/// <param name="whereLambda">条件 lambda表达式</param>
/// <param name="orderBy">排序 lambda表达式</param>
/// <returns></returns>
public async Task<List<TEntity>> GetPagedList<TKey>(int pageIndex, int pageSize, Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, TKey>> orderByLambda, bool isAsc = true)
{
// 分页 一定注意: Skip 之前一定要 OrderBy
if (isAsc)
{
return await _db.Set<TEntity>().Where(whereLambda).OrderBy(orderByLambda).Skip((pageIndex - ) * pageSize).Take(pageSize).AsNoTracking().ToListAsync();
}
else
{
return await _db.Set<TEntity>().Where(whereLambda).OrderByDescending(orderByLambda).Skip((pageIndex - ) * pageSize).Take(pageSize).AsNoTracking().ToListAsync();
}
}
#endregion #region 6.1分页查询 带输出 +List<TEntity> GetPagedList<TKey>
/// <summary>
/// 分页查询 带输出
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <param name="pageIndex"></param>
/// <param name="pageSize"></param>
/// <param name="rowCount"></param>
/// <param name="whereLambda"></param>
/// <param name="orderBy"></param>
/// <param name="isAsc"></param>
/// <returns></returns>
public async Task<PageModel<TEntity>> GetPagedList<TKey>(Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, TKey>> orderByLambda, bool isAsc = true, int pageIndex = , int pageSize = )
{
var rowCount = await _db.Set<TEntity>().Where(whereLambda).CountAsync(); int pageCount = (Math.Ceiling(rowCount.ObjToDecimal() / pageSize.ObjToDecimal())).ObjToInt(); List<TEntity> list = null; if (isAsc)
{
list = await _db.Set<TEntity>().OrderBy(orderByLambda).Where(whereLambda).Skip((pageIndex - ) * pageSize).Take(pageSize).AsNoTracking().ToListAsync();
}
else
{
list = await _db.Set<TEntity>().OrderByDescending(orderByLambda).Where(whereLambda).Skip((pageIndex - ) * pageSize).Take(pageSize).AsNoTracking().ToListAsync();
} return new PageModel<TEntity>() { dataCount = rowCount, pageCount = pageCount, page = pageIndex, PageSize = pageSize, data = list };
}
#endregion #endregion #region ORTHER /// <summary>
/// 执行存储过程或自定义sql语句--返回集合
/// </summary>
/// <param name="sql"></param>
/// <param name="parms"></param>
/// <param name="cmdType"></param>
/// <returns></returns>
public async Task<List<TEntity>> Query(string sql, List<SqlParameter> parms, CommandType cmdType = CommandType.Text)
{
//存储过程(exec getActionUrlId @name,@ID)
if (cmdType == CommandType.StoredProcedure)
{
StringBuilder paraNames = new StringBuilder();
foreach (var sqlPara in parms)
{
paraNames.Append($" @{sqlPara},");
}
sql = paraNames.Length > ? $"exec {sql} {paraNames.ToString().Trim(',')}" : $"exec {sql} ";
} return await _db.Set<TEntity>().FromSql(sql).ToListAsync(); } /// <summary>
/// 回滚
/// </summary>
public void RollBackChanges()
{
var items = _db.ChangeTracker.Entries().ToList();
items.ForEach(o => o.State = EntityState.Unchanged);
} /// <summary>
/// 自定义语句和存储过程的增删改--返回影响的行数
/// </summary>
/// <param name="sql"></param>
/// <param name="parms"></param>
/// <param name="cmdType"></param>
/// <returns></returns>
public async Task<int> Execute(string sql, List<SqlParameter> parms, CommandType cmdType = CommandType.Text)
{
//存储过程(exec getActionUrlId @name,@ID)
if (cmdType == CommandType.StoredProcedure)
{
StringBuilder paraNames = new StringBuilder();
foreach (var sqlPara in parms)
{
paraNames.Append($" @{sqlPara},");
}
sql = paraNames.Length > ?
$"exec {sql} {paraNames.ToString().Trim(',')}" :
$"exec {sql} ";
} int ret = await _db.Database.ExecuteSqlCommandAsync(sql, parms.ToArray());
return ;
} #endregion ORTHER
}
}
BaseRepository中主要是实现了一些基础的CURD操作,并且封装了一些常用的数据库操作。比如分页、执行sql语句等等
如果直接复制以上代码,会报错,因为你的项目中还没有数据上下文:
下面就引入我们将要使用的ORM框架--EFCore
首先,在model层总引入:
Install-Package Microsoft.EntityFrameworkCore -version 2.2.4
Install-Package Microsoft.EntityFrameworkCore.SqlServer -version 2.2.4
Install-Package Microsoft.EntityFrameworkCore.Tools -version 2.2.4
此系类中我们采用databaseFrist的方式来生成Model文件和上下文。在数据库中先建用于测试的表--Advertisement
语句如下:
USE [BaseCore]
GO /****** Object: Table [dbo].[Advertisement] Script Date: 08/28/2019 10:43:34 ******/
SET ANSI_NULLS ON
GO SET QUOTED_IDENTIFIER ON
GO CREATE TABLE [dbo].[Advertisement](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Createdate] [datetime] NOT NULL,
[ImgUrl] [nvarchar](512) NULL,
[Title] [nvarchar](64) NULL,
[Url] [nvarchar](256) NULL,
[Remark] [nvarchar](max) NULL,
CONSTRAINT [PK_dbo.Advertisement] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] GO
然后使用工具Scaffold-DbContext(数据库上下文脚手架)来生成model类文件和DbContext。
命令如下:
Scaffold-DbContext "server=.;database=XXX;uid=sa;pwd=密码;" Microsoft.EntityFrameworkCore.SqlServer -O Models -F -Context BaseCoreContext
在执行这个命令之前,需要将Model层设置为启动项目。否则会报错。
另外当你的项目Buid没有通过的话,会出现如下错误。
我一般的解决方案就是将其他项目全部先卸载,只留下一个Model,然后再执行以上语句。
这时,在你的Model项目下的Models文件夹下,就会出现如下文件:
打开BaseCoreContext.cs 文件,删除OnConfiguring 方法,至于为什么,我会在后面说明。
为了让数据库上下文也能用DI的方式进行使用,我新建了一个, IBaseContext接口,并且让BaseCoreContext 实现这个接口。
这个时候,仓储的基础父类应该是不会报错。但是我在BaseCoreContext里实现了一个分页操作,用到了一个PageModel 。需要添加到你的Model层里面
代码如下:
using System;
using System.Collections.Generic;
using System.Text; namespace Sincere.Core.Model
{
/// <summary>
/// 通用分页信息类
/// </summary>
public class PageModel<T>
{
/// <summary>
/// 当前页标
/// </summary>
public int page { get; set; } = ;
/// <summary>
/// 总页数
/// </summary>
public int pageCount { get; set; } = ;
/// <summary>
/// 数据总数
/// </summary>
public int dataCount { get; set; } = ;
/// <summary>
/// 每页大小
/// </summary>
public int PageSize { set; get; }
/// <summary>
/// 返回数据
/// </summary>
public List<T> data { get; set; } }
}
另外里面还有一些 转换函数,请参考源码:https://github.com/xzhencheng/Sincere.Core.git
至此,项目的仓储层的基础代码就构建完了,今天的作业就先写到这!
.netCore+Vue 搭建的简捷开发框架 (2)--仓储层实现和EFCore 的使用的更多相关文章
- .netCore+Vue 搭建的简捷开发框架 (3)-- Services层实现
继续交作业: 上一篇作业中我们实现了 Repository仓储层的应用.并为我们的框架引入了EFCore 详见: .netCore+Vue 搭建的简捷开发框架 (2)--仓储层实现和EFCore 的使 ...
- .netCore+Vue 搭建的简捷开发框架 (5)
文章目录:.netCore+Vue 搭建的简捷开发框架--目录 上两节的内容介绍了一些关于.netCore 相关的一些基础知识.介绍这些的目的,最主要的还是为了我们的架构搭建服务. 上一节中,我们介绍 ...
- .netCore+Vue 搭建的简捷开发框架--目录
.netCore+Vue 搭建的简捷开发框架 .netCore+Vue 搭建的简捷开发框架 (2)--仓储层实现和EFCore 的使用 .netCore+Vue 搭建的简捷开发框架 (3)-- Ser ...
- .netCore+Vue 搭建的简捷开发框架
话不多说,上图: 整体项目结构如图所示,我的设计初衷是基于.netCore + DI + Vue 打造一个适合初学者的简捷开发框架. 架构模型采用基于RESTful API风格的前后台分离框架,总体分 ...
- .netCore+Vue 搭建的简捷开发框架 (4)--NetCore 基础
书接上文:上一节中,我们已经实现Services 层.(https://www.cnblogs.com/xuzhencheng/p/11424751.html) 但是具体要如何将服务依赖注入进来呢?继 ...
- .netCore+Vue 搭建的简捷开发框架 (4)--NetCore 基础 -2
上节中,我们初步的介绍了一下NetCore的一些基础知识,为了控制篇幅(其实也是因为偷懒),我将NetCore 基础分为两部分来写. 0.WebAPI 项目的建立 1..NetCore 项目执行(加载 ...
- ASP.NET MVC系列 框架搭建(二)之仓储层的优化
大神勿喷,小神默默学. 会了就是不值一提的东西,不会就是绝对的高大上. 最后上传源码.希望能给读者带来一些新的认识及知识. 还没上过头条..各位大神,请点支持一下小弟. 陆续更新.更新到你会为止!! ...
- ASP.NET MVC系列 框架搭建(一)之仓储层的搭建
大神勿喷,小神默默学. 会了就是不值一提的东西,不会就是绝对的高大上. 最后上传源码.希望能给读者带来一些新的认识及知识. 还没上过头条..各位大神,请点支持一下小弟. 陆续更新.更新到你会为止!! ...
- .netcore+vue+elementUI 前后端分离---支持前端、后台业务代码扩展的快速开发框架
框架采用.NetCore + Vue前后端分离,并且支持前端.后台代码业务动态扩展,框架内置了一套有着20多种属性配置的代码生成器,可灵活配置生成的代码,代码生成器界面配置完成即可生成单表(主表)的增 ...
随机推荐
- MySQL隔离性及Spring事务
一.数据库事务ACID特性 必须要掌握事务的4个特性,其中事务的隔离性之于MySQL,对应4级隔离级别. 原子性(Atomicity): 事务中的所有原子操作,要么都能成功完成,要么都不完成,不能停滞 ...
- 夜空中最靓的二狗子是如何让 HTTPS 快上加快的?
二狗子是某不知名网站的站长,他热衷于通过博客分享日常的一些工作.生活.技术等,立志要成为夜空中最靓的仔. 但是前段时间有几个用户反馈,网站总是莫名会跳转到一个 xx 网站,除此之外访问速度也有点慢.作 ...
- egret之红包满屏随意飘动
在做这个需求之前,我们假设屏幕上同时飘动的红包数最大为10 ) { let redBag = GameUtil.createBitmapByName("Red_bag_png"); ...
- Leetcode之深度优先搜索(DFS)专题-473. 火柴拼正方形(Matchsticks to Square)
Leetcode之深度优先搜索(DFS)专题-473. 火柴拼正方形(Matchsticks to Square) 深度优先搜索的解题详细介绍,点击 还记得童话<卖火柴的小女孩>吗?现在, ...
- XHTML 和 HTML 中的 iframe
1. XHTML 有什么? XHTML是更严谨更纯净的HTML版本. 2.HTML和XHTML之间的差异 ①XHTML元素必须被正确的嵌套 /!--错误写法--/ <p><i> ...
- JIRA使用过程出现问题整理解答
转自:http://www.51testing.com/html/44/n-2820444.html 发表于:2015-5-28 10:22 作者:知乎 来源:51Testing软件测试网采编 ...
- wps10.1中将txt转为excel
1.将想要保存的内容保存为txt格式,用分隔符分隔好(包括空格.制表符.英文的逗号以及分号四种). 2.打开wps 3.点击数据->导入数据,选择刚才的txt文件 4.一步步操作,即可.
- A-Graph Games_2019牛客暑期多校训练营(第三场)
题意 给出一张无向图,定义S[x]表示与点x直接相连的点集,有两个操作 1 x y表示将第x到第y条边状态变化(若存在则删除,不存在则建立) 2 x y询问S[x]与S[y]是否相等 题解 有一个技巧 ...
- zstu19一月月赛 duxing201606的原味鸡树
duxing201606的原味鸡树 题意: 给定一颗有n(n<=1e9)个节点的完全二叉树,1e5次询问,问某个节点有几个子节点. 思路: 自己在月赛上没有思路,问了zfq才知道. 设两个指标, ...
- zoj 3261 Connections in Galaxy War(并查集逆向加边)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3261 题意:有很多颗星球,各自有武力值,星球间有一些联系通道,现 ...