书接上文,继续搭建我们基于.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. 如何在不到12天的时间里将网站权重优化到1(纯白帽SEO方法)

    之前操作了一个IDC网站,不到1个月的时间把网站的权重从0做到了1,本来想写篇文章分享相关的操作经验.后来因为网站整体规划的原因,IDC网站需要关闭一段时间做备案的更新,排名肯定就会掉了,然后怕大家看 ...

  2. Django上线部署之Apache

    环境: 1.Windows Server 2016 Datacenter 64位 2.SQL Server 2016 Enterprise 64位 3.Python 3.6.0 64位 4.admin ...

  3. 多渠道推广场景下,如何实现 App 用户增长的精准归因?

    为了实现用户的快速增长,以推广 App 为目标的线上广告投放是很多平台获取新用户的重要方式.随道移动互联网的发展,现在 App 推广的渠道越来越丰富,除了 WAP 站点.第三方 App 之外,HTML ...

  4. mysql的优化策略

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  5. Java 迭代接口:Iterator、ListIterator 和 Spliterator

    1. 简介 当我们使用 for 或 while 循环来遍历一个集合的元素,Iterator 允许我们不用担心索引位置,甚至让我们不仅仅是遍历一个集合,同时还可以改变它.例如,你如果要删除循环中的元素, ...

  6. Liunx学习总结(九)--防火墙

    防火墙的作用 防火墙作为一个边界防御工具,其监控流量要么允许它.要么屏蔽它. 多年来,防火墙的功能不断增强,现在大多数防火墙不仅可以阻止已知的一些威胁.执行高级访问控制列表策略,还可以深入检查流量中的 ...

  7. JMeter特点&性能测试工具选型的原则&模拟压力的原理

    1.JMeter自身的特点 1)开源.轻量级.更适合自动化和持续集成(100M左右,LoadRunner 4G左右) 2)学习难度大 3)资料少.全英文 2. 性能测试工具选型的原则 1)成本 a.工 ...

  8. 2018中国大学生程序设计竞赛 - 网络选拔赛 hdu Find Integer 数论

    Find Integer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  9. lightoj 1119 - Pimp My Ride(状压dp)

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1119 题解:状压dp存一下车有没有被搞过的状态就行. #include < ...

  10. 牛客第五场多校 A gpa 分数规划(模板)

    链接:https://www.nowcoder.com/acm/contest/143/A来源:牛客网 Kanade selected n courses in the university. The ...