ASP.NET CORE API 第二篇 项目整体搭建 轻量级ORM
原文作者:老张的哲学
零、今天完成的蓝色部分
image.png
0、创建实体模型与数据库.
1、实体模型
在上篇文章中,我们说到了仓储模式,所谓仓储,就是对数据的管理,因此,我们就必须要有实体模型,下文说到了 Advertisement ,那就先创建它的实体模型,其他的相关模型,大家自行下载代码即可:
using System;
namespace Blog.Core.Model
{
public class Advertisement
{
/// <summary>
/// Id
/// </summary>
public int Id { get; set; }
/// <summary>
/// 广告图片
/// </summary>
public string ImgUrl { get; set; }
/// <summary>
/// 广告标题
/// </summary>
public string title { get; set; }
/// <summary>
/// 广告链接
/// </summary>
public string Url { get; set; }
/// <summary>
/// 备注
/// </summary>
public string Remark { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime Createdate { get; set; } = DateTime.Now;
}
}
2、创建数据库
既然要操作数据库,肯定得先有一个数据库,这里提供了两种方式:
1、Sql语句生成(目前已经不更新,如果一定想要,去群文件下载)
2、通过我的项目,code first 生成,并且里边可以直接 seed data,这样就能生成一个完整的带数据的Database。
具体如何操作可以查看文章——《支持多种数据库 & 快速数据库生成》,如果你感觉麻烦,就自己根据上边的实体模型,自己创建一个数据库。
一、在 IRepository 层设计接口
还记得昨天我们实现的Sum接口么,今天在仓储接口 IAdvertisementRepository.cs 添加CURD四个接口,首先需要将Model层添加引用,这个应该都会,以后不再细说,如下:
using Blog.Core.Model;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace Blog.Core.IRespository
{
public interface IAdvertisementRepository
{
int Sum(int i, int j);
int Add(Advertisement model);
bool Delete(Advertisement model);
bool Update(Advertisement model);
List<Advertisement> Query(Expression<Func<Advertisement,bool>> whereExpression);
}
}
编译项目,提示错误,别慌!很正常,因为我们现在只是添加了接口,还没有实现接口。
二、在 Repository 层实现相应接口
当然,我们还是在AdvertisementRepository.cs文件中操作,这里我有一个小技巧,不知道大家是否用到过,因为我比较喜欢写接口,这样不仅可以不暴露核心代码,而且也可以让用户调用的时候,直接看到简单的接口方法列表,而不去管具体的实现过程,这样的设计思路还是比较提倡的,如下图:
image.png
你先看到了继承的接口有红色的波浪线,证明有错误,然后右键该接口,点击 Quick Actions and Refactorings...,也就是 快速操作和重构 ,你就会看到VS的智能提示,双击左侧的Implement interface,也就是实现接口,如下图:
image.png
Visual Studio真是宇宙第一IDE,没的说 [手动点赞],然后就创建成功了,你就可以去掉throw处理,自定义代码编写了,当然,如果你不习惯或者害怕出错,那就手动写吧,也是很快的。
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using Blog.Core.IRespository;
using Blog.Core.Model;
namespace Blog.Core.Respository
{
public class AdvertisementRepository : IAdvertisementRepository
{
public int Add(Advertisement model)
{
throw new NotImplementedException();
}
public bool Delete(Advertisement model)
{
throw new NotImplementedException();
}
public List<Advertisement> Query(Expression<Func<Advertisement, bool>> whereExpression)
{
throw new NotImplementedException();
}
public int Sum(int i, int j)
{
return i + j;
}
public bool Update(Advertisement model)
{
throw new NotImplementedException();
}
}
}
这个时候我们重新编译项目,嗯!意料之中,没有错误,但是具体的数据持久化如何写呢?
三、引用轻量级的ORM框架——SqlSugar
首先什么是ORM, 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。这些概念我就不细说了,自从开发这些年,一直在讨论的问题就是用ADO.NET还是用ORM框架,还记得前几年面试的时候,有一个经理问:
如果一个项目,你是用三层架构ADO,还是用ORM中的EF?
大家可以*留言,我表示各有千秋吧,一个产品的存在即有合理性,我平时项目中也有ADO,也有EF,不过本系列教程中基于面向对象思想,面向接口思想,当然还有以后的面向切面编程(AOP),还是使用ORM框架,不过是一个轻量级的,EF比较重,我在我其他的项目中用到了.Net MVC 6.0 + EF Code First 的项目,如果大家需要,我也开源出去,放在Github上,请文末留言吧~
关于ORM有一些常见的框架,如SqlSugar、Dapper、EF、NHeberneit等等,这些我都或多或少的了解过,使用过,至于你要问我为啥用SqlSugar,只要一个原因,作者是中国人,嗯!没错,这里给他打个广告,本系列中的前端框架Vue,也是我们中国的,Vue作者尤雨溪,这里也祝福大家都能有自己的成绩,为国人争光!
扯远了,开始动手引入框架:
开始,我们需要先向 Repository 层中引入SqlSugar,如下:
1)直接在类库中通过Nuget引入 sqlSugarCore,一定是Core版本的!,我个人采用这个办法,因为项目已经比较成型
2)Github下载源码,然后项目引用(点击跳转到Github下载页)
注意:为什么要单独在仓储层来引入ORM持久化接口,是因为,降低耦合,如果以后想要换成EF或者Deper,只需要修改Repository就行了,其他都不需要修改,达到很好的解耦效果。
image
编译一切正常,继续
首先呢,你需要了解下sqlsugar的具体使用方法,http://www.codeisbug.com/Doc/8,你先自己在控制台可以简单试一试,这里就不细说了,如果大家有需要,我可以单开一个文章,重点讲解SqlSugar这一块。
1、在Blog.Core.Repository新建一个sugar文件夹,然后添加两个配置文件,BaseDBConfig.cs 和 DbContext.cs ,这个你如果看了上边的文档,那这两个应该就不是问题。
using System.IO;
namespace Blog.Core.Respository.Sugar
{
public class BaseDBConfig
{
public static string ConnectionString = File.ReadAllText(@"C:\my-file\dbCountPsw1.txt").Trim();
//正常格式是
//public static string ConnectionString = "server=.;uid=sa;pwd=sa;database=BlogDB";
//原谅我用配置文件的形式,因为我直接调用的是我的服务器账号和密码,安全起见
}
}
DbContext.cs,一个详细的上下文类,看不懂没关系,以后我会详细讲解
using SqlSugar;
using System;
namespace Blog.Core.Repository
{
public class DbContext
{
private static string _connectionString;
private static DbType _dbType;
private SqlSugarClient _db;
/// <summary>
/// 连接字符串
/// Blog.Core
/// </summary>
public static string ConnectionString
{
get { return _connectionString; }
set { _connectionString = value; }
}
/// <summary>
/// 数据库类型
/// Blog.Core
/// </summary>
public static DbType DbType
{
get { return _dbType; }
set { _dbType = value; }
}
/// <summary>
/// 数据连接对象
/// Blog.Core
/// </summary>
public SqlSugarClient Db
{
get { return _db; }
private set { _db = value; }
}
/// <summary>
/// 数据库上下文实例(自动关闭连接)
/// Blog.Core
/// </summary>
public static DbContext Context
{
get
{
return new DbContext();
}
}
/// <summary>
/// 功能描述:构造函数
/// 作 者:Blog.Core
/// </summary>
private DbContext()
{
if (string.IsNullOrEmpty(_connectionString))
throw new ArgumentNullException("数据库连接字符串为空");
_db = new SqlSugarClient(new ConnectionConfig()
{
ConnectionString = _connectionString,
DbType = _dbType,
IsAutoCloseConnection = true,
IsShardSameThread = true,
ConfigureExternalServices = new ConfigureExternalServices()
{
//DataInfoCacheService = new HttpRuntimeCache()
},
MoreSettings = new ConnMoreSettings()
{
//IsWithNoLockQuery = true,
IsAutoRemoveDataCache = true
}
});
}
/// <summary>
/// 功能描述:构造函数
/// 作 者:Blog.Core
/// </summary>
/// <param name="blnIsAutoCloseConnection">是否自动关闭连接</param>
private DbContext(bool blnIsAutoCloseConnection)
{
if (string.IsNullOrEmpty(_connectionString))
throw new ArgumentNullException("数据库连接字符串为空");
_db = new SqlSugarClient(new ConnectionConfig()
{
ConnectionString = _connectionString,
DbType = _dbType,
IsAutoCloseConnection = blnIsAutoCloseConnection,
IsShardSameThread = true,
ConfigureExternalServices = new ConfigureExternalServices()
{
//DataInfoCacheService = new HttpRuntimeCache()
},
MoreSettings = new ConnMoreSettings()
{
//IsWithNoLockQuery = true,
IsAutoRemoveDataCache = true
}
});
}
#region 实例方法
/// <summary>
/// 功能描述:获取数据库处理对象
/// 作 者:Blog.Core
/// </summary>
/// <returns>返回值</returns>
public SimpleClient<T> GetEntityDB<T>() where T : class, new()
{
return new SimpleClient<T>(_db);
}
/// <summary>
/// 功能描述:获取数据库处理对象
/// 作 者:Blog.Core
/// </summary>
/// <param name="db">db</param>
/// <returns>返回值</returns>
public SimpleClient<T> GetEntityDB<T>(SqlSugarClient db) where T : class, new()
{
return new SimpleClient<T>(db);
}
#region 根据数据库表生产实体类
/// <summary>
/// 功能描述:根据数据库表生产实体类
/// 作 者:Blog.Core
/// </summary>
/// <param name="strPath">实体类存放路径</param>
public void CreateClassFileByDBTalbe(string strPath)
{
CreateClassFileByDBTalbe(strPath, "Km.PosZC");
}
/// <summary>
/// 功能描述:根据数据库表生产实体类
/// 作 者:Blog.Core
/// </summary>
/// <param name="strPath">实体类存放路径</param>
/// <param name="strNameSpace">命名空间</param>
public void CreateClassFileByDBTalbe(string strPath, string strNameSpace)
{
CreateClassFileByDBTalbe(strPath, strNameSpace, null);
}
/// <summary>
/// 功能描述:根据数据库表生产实体类
/// 作 者:Blog.Core
/// </summary>
/// <param name="strPath">实体类存放路径</param>
/// <param name="strNameSpace">命名空间</param>
/// <param name="lstTableNames">生产指定的表</param>
public void CreateClassFileByDBTalbe(
string strPath,
string strNameSpace,
string[] lstTableNames)
{
CreateClassFileByDBTalbe(strPath, strNameSpace, lstTableNames, string.Empty);
}
/// <summary>
/// 功能描述:根据数据库表生产实体类
/// 作 者:Blog.Core
/// </summary>
/// <param name="strPath">实体类存放路径</param>
/// <param name="strNameSpace">命名空间</param>
/// <param name="lstTableNames">生产指定的表</param>
/// <param name="strInterface">实现接口</param>
public void CreateClassFileByDBTalbe(
string strPath,
string strNameSpace,
string[] lstTableNames,
string strInterface,
bool blnSerializable = false)
{
if (lstTableNames != null && lstTableNames.Length > 0)
{
_db.DbFirst.Where(lstTableNames).IsCreateDefaultValue().IsCreateAttribute()
.SettingClassTemplate(p => p = @"
{using}
namespace {Namespace}
{
{ClassDescription}{SugarTable}" + (blnSerializable ? "[Serializable]" : "") + @"
public partial class {ClassName}" + (string.IsNullOrEmpty(strInterface) ? "" : (" : " + strInterface)) + @"
{
public {ClassName}()
{
{Constructor}
}
{PropertyName}
}
}
")
.SettingPropertyTemplate(p => p = @"
{SugarColumn}
public {PropertyType} {PropertyName}
{
get
{
return _{PropertyName};
}
set
{
if(_{PropertyName}!=value)
{
base.SetValueCall(" + "\"{PropertyName}\",_{PropertyName}" + @");
}
_{PropertyName}=value;
}
}")
.SettingPropertyDescriptionTemplate(p => p = " private {PropertyType} _{PropertyName};\r\n" + p)
.SettingConstructorTemplate(p => p = " this._{PropertyName} ={DefaultValue};")
.CreateClassFile(strPath, strNameSpace);
}
else
{
_db.DbFirst.IsCreateAttribute().IsCreateDefaultValue()
.SettingClassTemplate(p => p = @"
{using}
namespace {Namespace}
{
{ClassDescription}{SugarTable}" + (blnSerializable ? "[Serializable]" : "") + @"
public partial class {ClassName}" + (string.IsNullOrEmpty(strInterface) ? "" : (" : " + strInterface)) + @"
{
public {ClassName}()
{
{Constructor}
}
{PropertyName}
}
}
")
.SettingPropertyTemplate(p => p = @"
{SugarColumn}
public {PropertyType} {PropertyName}
{
get
{
return _{PropertyName};
}
set
{
if(_{PropertyName}!=value)
{
base.SetValueCall(" + "\"{PropertyName}\",_{PropertyName}" + @");
}
_{PropertyName}=value;
}
}")
.SettingPropertyDescriptionTemplate(p => p = " private {PropertyType} _{PropertyName};\r\n" + p)
.SettingConstructorTemplate(p => p = " this._{PropertyName} ={DefaultValue};")
.CreateClassFile(strPath, strNameSpace);
}
}
#endregion
#region 根据实体类生成数据库表
/// <summary>
/// 功能描述:根据实体类生成数据库表
/// 作 者:Blog.Core
/// </summary>
/// <param name="blnBackupTable">是否备份表</param>
/// <param name="lstEntitys">指定的实体</param>
public void CreateTableByEntity<T>(bool blnBackupTable, params T[] lstEntitys) where T : class, new()
{
Type[] lstTypes = null;
if (lstEntitys != null)
{
lstTypes = new Type[lstEntitys.Length];
for (int i = 0; i < lstEntitys.Length; i++)
{
T t = lstEntitys[i];
lstTypes[i] = typeof(T);
}
}
CreateTableByEntity(blnBackupTable, lstTypes);
}
/// <summary>
/// 功能描述:根据实体类生成数据库表
/// 作 者:Blog.Core
/// </summary>
/// <param name="blnBackupTable">是否备份表</param>
/// <param name="lstEntitys">指定的实体</param>
public void CreateTableByEntity(bool blnBackupTable, params Type[] lstEntitys)
{
if (blnBackupTable)
{
_db.CodeFirst.BackupTable().InitTables(lstEntitys); //change entity backupTable
}
else
{
_db.CodeFirst.InitTables(lstEntitys);
}
}
#endregion
#endregion
#region 静态方法
/// <summary>
/// 功能描述:获得一个DbContext
/// 作 者:Blog.Core
/// </summary>
/// <param name="blnIsAutoCloseConnection">是否自动关闭连接(如果为false,则使用接受时需要手动关闭Db)</param>
/// <returns>返回值</returns>
public static DbContext GetDbContext(bool blnIsAutoCloseConnection = true)
{
return new DbContext(blnIsAutoCloseConnection);
}
/// <summary>
/// 功能描述:设置初始化参数
/// 作 者:Blog.Core
/// </summary>
/// <param name="strConnectionString">连接字符串</param>
/// <param name="enmDbType">数据库类型</param>
public static void Init(string strConnectionString, DbType enmDbType = SqlSugar.DbType.SqlServer)
{
_connectionString = strConnectionString;
_dbType = enmDbType;
}
/// <summary>
/// 功能描述:创建一个链接配置
/// 作 者:Blog.Core
/// </summary>
/// <param name="blnIsAutoCloseConnection">是否自动关闭连接</param>
/// <param name="blnIsShardSameThread">是否夸类事务</param>
/// <returns>ConnectionConfig</returns>
public static ConnectionConfig GetConnectionConfig(bool blnIsAutoCloseConnection = true, bool blnIsShardSameThread = false)
{
ConnectionConfig config = new ConnectionConfig()
{
ConnectionString = _connectionString,
DbType = _dbType,
IsAutoCloseConnection = blnIsAutoCloseConnection,
ConfigureExternalServices = new ConfigureExternalServices()
{
//DataInfoCacheService = new HttpRuntimeCache()
},
IsShardSameThread = blnIsShardSameThread
};
return config;
}
/// <summary>
/// 功能描述:获取一个自定义的DB
/// 作 者:Blog.Core
/// </summary>
/// <param name="config">config</param>
/// <returns>返回值</returns>
public static SqlSugarClient GetCustomDB(ConnectionConfig config)
{
return new SqlSugarClient(config);
}
/// <summary>
/// 功能描述:获取一个自定义的数据库处理对象
/// 作 者:Blog.Core
/// </summary>
/// <param name="sugarClient">sugarClient</param>
/// <returns>返回值</returns>
public static SimpleClient<T> GetCustomEntityDB<T>(SqlSugarClient sugarClient) where T : class, new()
{
return new SimpleClient<T>(sugarClient);
}
/// <summary>
/// 功能描述:获取一个自定义的数据库处理对象
/// 作 者:Blog.Core
/// </summary>
/// <param name="config">config</param>
/// <returns>返回值</returns>
public static SimpleClient<T> GetCustomEntityDB<T>(ConnectionConfig config) where T : class, new()
{
SqlSugarClient sugarClient = GetCustomDB(config);
return GetCustomEntityDB<T>(sugarClient);
}
#endregion
}
}
2、然后在刚刚我们实现那四个方法的AdvertisementRepository.cs中,重写构造函数,编辑统一Sqlsugar实例方法,用到了私有属性,为以后的单列模式做准备。
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using Blog.Core.IRespository;
using Blog.Core.Model;
using Blog.Core.Repository;
using Blog.Core.Respository.Sugar;
using SqlSugar;
namespace Blog.Core.Respository
{
public class AdvertisementRepository : IAdvertisementRepository
{
private DbContext context;
private SqlSugarClient db;
private SimpleClient<Advertisement> entityDB;
internal SqlSugarClient Db
{
get { return db; }
private set { db = value; }
}
public DbContext Context
{
get { return context; }
set { context = value; }
}
public AdvertisementRepository()
{
DbContext.Init(BaseDBConfig.ConnectionString);
context = DbContext.GetDbContext();
db = context.Db;
entityDB = context.GetEntityDB<Advertisement>(db);
}
public int Add(Advertisement model)
{
throw new NotImplementedException();
}
public bool Delete(Advertisement model)
{
throw new NotImplementedException();
}
public List<Advertisement> Query(Expression<Func<Advertisement, bool>> whereExpression)
{
throw new NotImplementedException();
}
public int Sum(int i, int j)
{
return i + j;
}
public bool Update(Advertisement model)
{
throw new NotImplementedException();
}
}
}
3、正式开始写持久化逻辑代码(注意:我在Model层中,添加了全局的数据类型转换方法,UtilConvert,这样就不用每次都Convert,而且也解决了为空转换异常的bug)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Blog.Core.Common
{
public static class UtilConvert
{
/// <summary>
///
/// </summary>
/// <param name="thisValue"></param>
/// <returns></returns>
public static int ObjToInt(this object thisValue)
{
int reval = 0;
if (thisValue == null) return 0;
if (thisValue != null && thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out reval))
{
return reval;
}
return reval;
}
/// <summary>
///
/// </summary>
/// <param name="thisValue"></param>
/// <param name="errorValue"></param>
/// <returns></returns>
public static int ObjToInt(this object thisValue, int errorValue)
{
int reval = 0;
if (thisValue != null && thisValue != DBNull.Value && int.TryParse(thisValue.ToString(), out reval))
{
return reval;
}
return errorValue;
}
/// <summary>
///
/// </summary>
/// <param name="thisValue"></param>
/// <returns></returns>
public static double ObjToMoney(this object thisValue)
{
double reval = 0;
if (thisValue != null && thisValue != DBNull.Value && double.TryParse(thisValue.ToString(), out reval))
{
return reval;
}
return 0;
}
/// <summary>
///
/// </summary>
/// <param name="thisValue"></param>
/// <param name="errorValue"></param>
/// <returns></returns>
public static double ObjToMoney(this object thisValue, double errorValue)
{
double reval = 0;
if (thisValue != null && thisValue != DBNull.Value && double.TryParse(thisValue.ToString(), out reval))
{
return reval;
}
return errorValue;
}
/// <summary>
///
/// </summary>
/// <param name="thisValue"></param>
/// <returns></returns>
public static string ObjToString(this object thisValue)
{
if (thisValue != null) return thisValue.ToString().Trim();
return "";
}
/// <summary>
///
/// </summary>
/// <param name="thisValue"></param>
/// <param name="errorValue"></param>
/// <returns></returns>
public static string ObjToString(this object thisValue, string errorValue)
{
if (thisValue != null) return thisValue.ToString().Trim();
return errorValue;
}
/// <summary>
///
/// </summary>
/// <param name="thisValue"></param>
/// <returns></returns>
public static Decimal ObjToDecimal(this object thisValue)
{
Decimal reval = 0;
if (thisValue != null && thisValue != DBNull.Value && decimal.TryParse(thisValue.ToString(), out reval))
{
return reval;
}
return 0;
}
/// <summary>
///
/// </summary>
/// <param name="thisValue"></param>
/// <param name="errorValue"></param>
/// <returns></returns>
public static Decimal ObjToDecimal(this object thisValue, decimal errorValue)
{
Decimal reval = 0;
if (thisValue != null && thisValue != DBNull.Value && decimal.TryParse(thisValue.ToString(), out reval))
{
return reval;
}
return errorValue;
}
/// <summary>
///
/// </summary>
/// <param name="thisValue"></param>
/// <returns></returns>
public static DateTime ObjToDate(this object thisValue)
{
DateTime reval = DateTime.MinValue;
if (thisValue != null && thisValue != DBNull.Value && DateTime.TryParse(thisValue.ToString(), out reval))
{
reval = Convert.ToDateTime(thisValue);
}
return reval;
}
/// <summary>
///
/// </summary>
/// <param name="thisValue"></param>
/// <param name="errorValue"></param>
/// <returns></returns>
public static DateTime ObjToDate(this object thisValue, DateTime errorValue)
{
DateTime reval = DateTime.MinValue;
if (thisValue != null && thisValue != DBNull.Value && DateTime.TryParse(thisValue.ToString(), out reval))
{
return reval;
}
return errorValue;
}
/// <summary>
///
/// </summary>
/// <param name="thisValue"></param>
/// <returns></returns>
public static bool ObjToBool(this object thisValue)
{
bool reval = false;
if (thisValue != null && thisValue != DBNull.Value && bool.TryParse(thisValue.ToString(), out reval))
{
return reval;
}
return reval;
}
}
}
最终的仓储持久化是:
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using Blog.Core.IRespository;
using Blog.Core.Model;
using Blog.Core.Repository;
using Blog.Core.Respository.Sugar;
using SqlSugar;
namespace Blog.Core.Respository
{
public class AdvertisementRepository : IAdvertisementRepository
{
private DbContext context;
private SqlSugarClient db;
private SimpleClient<Advertisement> entityDB;
internal SqlSugarClient Db
{
get { return db; }
private set { db = value; }
}
public DbContext Context
{
get { return context; }
set { context = value; }
}
public AdvertisementRepository()
{
DbContext.Init(BaseDBConfig.ConnectionString);
context = DbContext.GetDbContext();
db = context.Db;
entityDB = context.GetEntityDB<Advertisement>(db);
}
public int Add(Advertisement model)
{
// 返回的i是long类型,这里你可以根据你的业务需要进行处理
var i = db.Insertable(model).ExecuteReturnBigIdentity();
return i.ObjToInt();
}
public bool Delete(Advertisement model)
{
var i = db.Deleteable(model).ExecuteCommand();
return i > 0;
}
public List<Advertisement> Query(Expression<Func<Advertisement, bool>> whereExpression)
{
return entityDB.GetList(whereExpression);
}
public int Sum(int i, int j)
{
return i + j;
}
public bool Update(Advertisement model)
{
// 这种方式以主键为条件
var i = db.Updateable(model).ExecuteCommand();
return i > 0;
}
}
}
四、在 IServices 层设计服务接口,并 Service 层实现
这里不细说,记得添加引用,最终的代码是:
using Blog.Core.Model;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace Blog.Core.IServices
{
public interface IAdvertisementServices
{
int Sum(int i,int j);
int Add(Advertisement model);
bool Delete(Advertisement model);
bool Update(Advertisement model);
List<Advertisement> Query(Expression<Func<Advertisement, bool>> whereExpression);
}
}
using Blog.Core.IServices;
using Blog.Core.IRespository;
using Blog.Core.Respository;
using Blog.Core.Model;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace Blog.Core.Services
{
public class AdvertisementServices : IAdvertisementServices
{
IAdvertisementRepository dal = new AdvertisementRepository();
public int Add(Advertisement model)
{
return dal.Add(model);
}
public bool Delete(Advertisement model)
{
return dal.Delete(model);
}
public List<Advertisement> Query(Expression<Func<Advertisement, bool>> whereExpression)
{
return dal.Query(whereExpression);
}
public int Sum(int i, int j)
{
return dal.Sum(i, j);
}
public bool Update(Advertisement model)
{
return dal.Update(model);
}
}
}
都是很简单,如果昨天的Sum方法你会了,这个肯定都会。
五、Controller测试接口
实现工作,根据id获取数据
这里为了调试方便,我把权限验证暂时注释掉
//[Authorize(Policy ="Admin")]
image.png
然后修改我们的其中一个Get方法,根据id获取信息
/// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("{id}", Name = "Get")]
public List<Advertisement> Get(int id)
{
var advertisementService = new AdvertisementServices();
return advertisementService.Query(d => d.Id == id);
}
接下来运行调试,在我们接口文档中,直接点击调试
image.png
得到的结果是如果,虽然是空的,但是返回结果http代码是200,因为表中没数据嘛
image.png
六、结语
好啦,今天的讲解就到这里,你简单的了解了什么是ORM,以及其中的SqlSugar,然后呢,仓储模式的具体使用,最后还有真正的连接数据库,获取到数据,下一节中,我们继续来解决两大问题,来实现泛型仓储。
推荐阅读
-
【从零开始搭建自己的.NET Core Api框架】(三)集成轻量级ORM——SqlSugar:3.3 自动生成实体类
-
【从零开始搭建自己的.NET Core Api框架】(三)集成轻量级ORM——SqlSugar:3.2 在框架的基础上利用SqlSugar快速实现CRUD实战篇
-
【从零开始搭建自己的.NET Core Api框架】(二)搭建项目的整体架构
-
【从零开始搭建自己的.NET Core Api框架】(三)集成轻量级ORM——SqlSugar:3.1 搭建环境
-
ASP.NET Core 实战:使用 ASP.NET Core Web API 和 Vue.js 搭建前后端分离项目
-
【从零开始搭建自己的.NET Core Api框架】(三)集成轻量级ORM——SqlSugar:3.3 自动生成实体类
-
ASP.NET CORE API 第二篇 项目整体搭建 轻量级ORM
-
ASP.NET CORE API 第一篇 项目整体搭建 仓储+服务+抽象接口模式
-
ASP.NET CORE API 第三篇 项目整体搭建 异步泛型仓储+依赖注入初探
-
【从零开始搭建自己的.NET Core Api框架】(二)搭建项目的整体架构