书接上文,继续搭建我们基于.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.cs

这个时候,仓储的基础父类应该是不会报错。但是我在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 的使用的更多相关文章

  1. .netCore+Vue 搭建的简捷开发框架 (3)-- Services层实现

    继续交作业: 上一篇作业中我们实现了 Repository仓储层的应用.并为我们的框架引入了EFCore 详见: .netCore+Vue 搭建的简捷开发框架 (2)--仓储层实现和EFCore 的使 ...

  2. .netCore+Vue 搭建的简捷开发框架 (5)

    文章目录:.netCore+Vue 搭建的简捷开发框架--目录 上两节的内容介绍了一些关于.netCore 相关的一些基础知识.介绍这些的目的,最主要的还是为了我们的架构搭建服务. 上一节中,我们介绍 ...

  3. .netCore+Vue 搭建的简捷开发框架--目录

    .netCore+Vue 搭建的简捷开发框架 .netCore+Vue 搭建的简捷开发框架 (2)--仓储层实现和EFCore 的使用 .netCore+Vue 搭建的简捷开发框架 (3)-- Ser ...

  4. .netCore+Vue 搭建的简捷开发框架

    话不多说,上图: 整体项目结构如图所示,我的设计初衷是基于.netCore + DI + Vue 打造一个适合初学者的简捷开发框架. 架构模型采用基于RESTful API风格的前后台分离框架,总体分 ...

  5. .netCore+Vue 搭建的简捷开发框架 (4)--NetCore 基础

    书接上文:上一节中,我们已经实现Services 层.(https://www.cnblogs.com/xuzhencheng/p/11424751.html) 但是具体要如何将服务依赖注入进来呢?继 ...

  6. .netCore+Vue 搭建的简捷开发框架 (4)--NetCore 基础 -2

    上节中,我们初步的介绍了一下NetCore的一些基础知识,为了控制篇幅(其实也是因为偷懒),我将NetCore 基础分为两部分来写. 0.WebAPI 项目的建立 1..NetCore 项目执行(加载 ...

  7. ASP.NET MVC系列 框架搭建(二)之仓储层的优化

    大神勿喷,小神默默学. 会了就是不值一提的东西,不会就是绝对的高大上. 最后上传源码.希望能给读者带来一些新的认识及知识. 还没上过头条..各位大神,请点支持一下小弟. 陆续更新.更新到你会为止!! ...

  8. ASP.NET MVC系列 框架搭建(一)之仓储层的搭建

    大神勿喷,小神默默学. 会了就是不值一提的东西,不会就是绝对的高大上. 最后上传源码.希望能给读者带来一些新的认识及知识. 还没上过头条..各位大神,请点支持一下小弟. 陆续更新.更新到你会为止!! ...

  9. .netcore+vue+elementUI 前后端分离---支持前端、后台业务代码扩展的快速开发框架

    框架采用.NetCore + Vue前后端分离,并且支持前端.后台代码业务动态扩展,框架内置了一套有着20多种属性配置的代码生成器,可灵活配置生成的代码,代码生成器界面配置完成即可生成单表(主表)的增 ...

随机推荐

  1. Go最火的Gin框架简单入门

    Gin 介绍 Gin 是一个 Golang 写的 web 框架,具有高性能的优点,,基于 httprouter,它提供了类似martini但更好性能(路由性能约快40倍)的API服务.官方地址:htt ...

  2. hive explode 行拆列

    创建一张表test_explode,表结构如下 表数据如下: 1.使用explode函数 select explode(friends) as friend from test_explode; 但是 ...

  3. IoT时代:Wi-Fi“配网”技术剖析总结

    导读 近年来,物联网市场竞争激烈,从物联网平台厂商,设备生产商,到服务提供商,都在涌入这片红海.预计到2020年,全球联网设备数量将达到260亿个,年复合增长率达到20%:全球联网设备带来的数据将达到 ...

  4. Jmeter接口自动化实例(使用Beanshell保存csv文件、csv参数化、setUp线程组)

    很久没更新博客了,荒废了很久了,今天更新一下博客,主要记录一下子最近遇到的问题和解决方法:blonde_woman: 这篇文章主要记录的是jmeter批量跑接口中遇到的各种疑难,主要涉及到的问题如下 ...

  5. Android开发之输入框EditText介绍

    这篇文章主要为大家详细介绍了Android布局之输入框EditText设计,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 现在先简单介绍一下技术点: 1.如何使用圆角输入框和按钮背景 2.如何实现 ...

  6. SpringBoot:elasticSearch 7.2.0 Java High Level REST Client 搜索 API

    Springboot整合最新版elasticSearch参考之前的文章:SpingBoot:整合ElasticSearch 7.2.0 Search API SearchRequest用于与搜索文档, ...

  7. 90001PS相关操作

    第一章   PS基础操作 1.1 PS界面介绍 (1)界面包含:菜单栏.状态样式栏.工具栏.绘图区域.工作区. (2)布局可以在左上角进行切换,区分主要为工作区的侧重点不同. (3)布局想恢复可在窗口 ...

  8. Oracle数据库之四 简单查询

    四.简单查询 ​ 简单查询的主要特征就是将一张数据表之中的全部数据行进行显示,而后可以利用 SELECT 子句来控制所需要的输出列. 4.1.基础语法 范例:查询 emp 表中的数据(全部数据查询) ...

  9. Docker学习总结(三)--常用命令

    镜像相关命令 查看镜像 docker images 返回列表字段含义如下: 字段名称 字段含义 REPOSITORY 镜像名称 TAG 镜像标签 IMAGE ID 镜像 ID CREATED 镜像创建 ...

  10. LiteORM-For-DotNet,我的第一个开源库

    这是一个DotNet轻量级ORM框架,解决C#.Net开发过程中重复繁琐的数据库CURD操作. 前言 因工作中接手的.net项目,源码里面都用了动软代码生成的源码做为数据库操作类库.其中,有些根本就没 ...