原文作者:老張的哲學(xué)
零、今天完成的藍(lán)色部分
0示绊、創(chuàng)建實(shí)體模型與數(shù)據(jù)庫(kù).
1锭部、實(shí)體模型
在上篇文章中,我們說到了倉(cāng)儲(chǔ)模式面褐,所謂倉(cāng)儲(chǔ)拌禾,就是對(duì)數(shù)據(jù)的管理,因此展哭,我們就必須要有實(shí)體模型湃窍,下文說到了 Advertisement ,那就先創(chuàng)建它的實(shí)體模型匪傍,其他的相關(guān)模型您市,大家自行下載代碼即可:
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>
/// 廣告標(biāo)題
/// </summary>
public string title { get; set; }
/// <summary>
/// 廣告鏈接
/// </summary>
public string Url { get; set; }
/// <summary>
/// 備注
/// </summary>
public string Remark { get; set; }
/// <summary>
/// 創(chuàng)建時(shí)間
/// </summary>
public DateTime Createdate { get; set; } = DateTime.Now;
}
}
2、創(chuàng)建數(shù)據(jù)庫(kù)
既然要操作數(shù)據(jù)庫(kù)役衡,肯定得先有一個(gè)數(shù)據(jù)庫(kù)茵休,這里提供了兩種方式:
1、Sql語句生成(目前已經(jīng)不更新手蝎,如果一定想要榕莺,去群文件下載)
2、通過我的項(xiàng)目棵介,code first 生成帽撑,并且里邊可以直接 seed data,這樣就能生成一個(gè)完整的帶數(shù)據(jù)的Database鞍时。
具體如何操作可以查看文章——《支持多種數(shù)據(jù)庫(kù) & 快速數(shù)據(jù)庫(kù)生成》亏拉,如果你感覺麻煩扣蜻,就自己根據(jù)上邊的實(shí)體模型,自己創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)及塘。
一莽使、在 IRepository 層設(shè)計(jì)接口
還記得昨天我們實(shí)現(xiàn)的Sum接口么,今天在倉(cāng)儲(chǔ)接口 IAdvertisementRepository.cs 添加CURD四個(gè)接口笙僚,首先需要將Model層添加引用芳肌,這個(gè)應(yīng)該都會(huì),以后不再細(xì)說肋层,如下:
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);
}
}
編譯項(xiàng)目亿笤,提示錯(cuò)誤,別慌栋猖!很正常净薛,因?yàn)槲覀儸F(xiàn)在只是添加了接口,還沒有實(shí)現(xiàn)接口蒲拉。
二肃拜、在 Repository 層實(shí)現(xiàn)相應(yīng)接口
當(dāng)然,我們還是在AdvertisementRepository.cs文件中操作雌团,這里我有一個(gè)小技巧燃领,不知道大家是否用到過,因?yàn)槲冶容^喜歡寫接口锦援,這樣不僅可以不暴露核心代碼猛蔽,而且也可以讓用戶調(diào)用的時(shí)候,直接看到簡(jiǎn)單的接口方法列表灵寺,而不去管具體的實(shí)現(xiàn)過程枢舶,這樣的設(shè)計(jì)思路還是比較提倡的,如下圖:
你先看到了繼承的接口有紅色的波浪線替久,證明有錯(cuò)誤,然后右鍵該接口躏尉,點(diǎn)擊 Quick Actions and Refactorings...蚯根,也就是 快速操作和重構(gòu) ,你就會(huì)看到VS的智能提示胀糜,雙擊左側(cè)的Implement interface颅拦,也就是實(shí)現(xiàn)接口,如下圖:
Visual Studio真是宇宙第一IDE教藻,沒的說 [手動(dòng)點(diǎn)贊]距帅,然后就創(chuàng)建成功了,你就可以去掉throw處理括堤,自定義代碼編寫了碌秸,當(dāng)然绍移,如果你不習(xí)慣或者害怕出錯(cuò),那就手動(dòng)寫吧讥电,也是很快的蹂窖。
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();
}
}
}
這個(gè)時(shí)候我們重新編譯項(xiàng)目,嗯恩敌!意料之中瞬测,沒有錯(cuò)誤,但是具體的數(shù)據(jù)持久化如何寫呢纠炮?
三月趟、引用輕量級(jí)的ORM框架——SqlSugar
首先什么是ORM, 對(duì)象關(guān)系映射(Object Relational Mapping恢口,簡(jiǎn)稱ORM)模式是一種為了解決面向?qū)ο笈c關(guān)系數(shù)據(jù)庫(kù)存在的互不匹配的現(xiàn)象的技術(shù)孝宗。簡(jiǎn)單的說,ORM是通過使用描述對(duì)象和數(shù)據(jù)庫(kù)之間映射的元數(shù)據(jù)弧蝇,將程序中的對(duì)象自動(dòng)持久化到關(guān)系數(shù)據(jù)庫(kù)中碳褒。這些概念我就不細(xì)說了,自從開發(fā)這些年看疗,一直在討論的問題就是用ADO.NET還是用ORM框架沙峻,還記得前幾年面試的時(shí)候,有一個(gè)經(jīng)理問:
如果一個(gè)項(xiàng)目两芳,你是用三層架構(gòu)ADO摔寨,還是用ORM中的EF?
大家可以自由留言怖辆,我表示各有千秋吧是复,一個(gè)產(chǎn)品的存在即有合理性,我平時(shí)項(xiàng)目中也有ADO竖螃,也有EF淑廊,不過本系列教程中基于面向?qū)ο笏枷耄嫦蚪涌谒枷胩嘏兀?dāng)然還有以后的面向切面編程(AOP)季惩,還是使用ORM框架,不過是一個(gè)輕量級(jí)的腻格,EF比較重画拾,我在我其他的項(xiàng)目中用到了.Net MVC 6.0 + EF Code First 的項(xiàng)目,如果大家需要菜职,我也開源出去青抛,放在Github上,請(qǐng)文末留言吧~
關(guān)于ORM有一些常見的框架酬核,如SqlSugar蜜另、Dapper适室、EF、NHeberneit等等蚕钦,這些我都或多或少的了解過亭病,使用過,至于你要問我為啥用SqlSugar嘶居,只要一個(gè)原因罪帖,作者是中國(guó)人,嗯邮屁!沒錯(cuò)整袁,這里給他打個(gè)廣告,本系列中的前端框架Vue佑吝,也是我們中國(guó)的坐昙,Vue作者尤雨溪,這里也祝福大家都能有自己的成績(jī)芋忿,為國(guó)人爭(zhēng)光炸客!
扯遠(yuǎn)了,開始動(dòng)手引入框架:
開始戈钢,我們需要先向 Repository 層中引入SqlSugar痹仙,如下:
1)直接在類庫(kù)中通過Nuget引入 sqlSugarCore,一定是Core版本的殉了!开仰,我個(gè)人采用這個(gè)辦法,因?yàn)轫?xiàng)目已經(jīng)比較成型
2)Github下載源碼薪铜,然后項(xiàng)目引用(點(diǎn)擊跳轉(zhuǎn)到Github下載頁(yè))
注意:為什么要單獨(dú)在倉(cāng)儲(chǔ)層來引入ORM持久化接口众弓,是因?yàn)椋档婉詈细艄浚绻院笙胍獡Q成EF或者Deper谓娃,只需要修改Repository就行了,其他都不需要修改蜒滩,達(dá)到很好的解耦效果滨达。
編譯一切正常,繼續(xù)
首先呢帮掉,你需要了解下sqlsugar的具體使用方法,http://www.codeisbug.com/Doc/8窒典,你先自己在控制臺(tái)可以簡(jiǎn)單試一試蟆炊,這里就不細(xì)說了,如果大家有需要瀑志,我可以單開一個(gè)文章涩搓,重點(diǎn)講解SqlSugar這一塊污秆。
1、在Blog.Core.Repository新建一個(gè)sugar文件夾昧甘,然后添加兩個(gè)配置文件良拼,BaseDBConfig.cs 和 DbContext.cs ,這個(gè)你如果看了上邊的文檔充边,那這兩個(gè)應(yīng)該就不是問題庸推。
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";
//原諒我用配置文件的形式,因?yàn)槲抑苯诱{(diào)用的是我的服務(wù)器賬號(hào)和密碼浇冰,安全起見
}
}
DbContext.cs贬媒,一個(gè)詳細(xì)的上下文類,看不懂沒關(guān)系肘习,以后我會(huì)詳細(xì)講解
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>
/// 數(shù)據(jù)庫(kù)類型
/// Blog.Core
/// </summary>
public static DbType DbType
{
get { return _dbType; }
set { _dbType = value; }
}
/// <summary>
/// 數(shù)據(jù)連接對(duì)象
/// Blog.Core
/// </summary>
public SqlSugarClient Db
{
get { return _db; }
private set { _db = value; }
}
/// <summary>
/// 數(shù)據(jù)庫(kù)上下文實(shí)例(自動(dòng)關(guān)閉連接)
/// Blog.Core
/// </summary>
public static DbContext Context
{
get
{
return new DbContext();
}
}
/// <summary>
/// 功能描述:構(gòu)造函數(shù)
/// 作 者:Blog.Core
/// </summary>
private DbContext()
{
if (string.IsNullOrEmpty(_connectionString))
throw new ArgumentNullException("數(shù)據(jù)庫(kù)連接字符串為空");
_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>
/// 功能描述:構(gòu)造函數(shù)
/// 作 者:Blog.Core
/// </summary>
/// <param name="blnIsAutoCloseConnection">是否自動(dòng)關(guān)閉連接</param>
private DbContext(bool blnIsAutoCloseConnection)
{
if (string.IsNullOrEmpty(_connectionString))
throw new ArgumentNullException("數(shù)據(jù)庫(kù)連接字符串為空");
_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 實(shí)例方法
/// <summary>
/// 功能描述:獲取數(shù)據(jù)庫(kù)處理對(duì)象
/// 作 者:Blog.Core
/// </summary>
/// <returns>返回值</returns>
public SimpleClient<T> GetEntityDB<T>() where T : class, new()
{
return new SimpleClient<T>(_db);
}
/// <summary>
/// 功能描述:獲取數(shù)據(jù)庫(kù)處理對(duì)象
/// 作 者: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 根據(jù)數(shù)據(jù)庫(kù)表生產(chǎn)實(shí)體類
/// <summary>
/// 功能描述:根據(jù)數(shù)據(jù)庫(kù)表生產(chǎn)實(shí)體類
/// 作 者:Blog.Core
/// </summary>
/// <param name="strPath">實(shí)體類存放路徑</param>
public void CreateClassFileByDBTalbe(string strPath)
{
CreateClassFileByDBTalbe(strPath, "Km.PosZC");
}
/// <summary>
/// 功能描述:根據(jù)數(shù)據(jù)庫(kù)表生產(chǎn)實(shí)體類
/// 作 者:Blog.Core
/// </summary>
/// <param name="strPath">實(shí)體類存放路徑</param>
/// <param name="strNameSpace">命名空間</param>
public void CreateClassFileByDBTalbe(string strPath, string strNameSpace)
{
CreateClassFileByDBTalbe(strPath, strNameSpace, null);
}
/// <summary>
/// 功能描述:根據(jù)數(shù)據(jù)庫(kù)表生產(chǎn)實(shí)體類
/// 作 者:Blog.Core
/// </summary>
/// <param name="strPath">實(shí)體類存放路徑</param>
/// <param name="strNameSpace">命名空間</param>
/// <param name="lstTableNames">生產(chǎn)指定的表</param>
public void CreateClassFileByDBTalbe(
string strPath,
string strNameSpace,
string[] lstTableNames)
{
CreateClassFileByDBTalbe(strPath, strNameSpace, lstTableNames, string.Empty);
}
/// <summary>
/// 功能描述:根據(jù)數(shù)據(jù)庫(kù)表生產(chǎn)實(shí)體類
/// 作 者:Blog.Core
/// </summary>
/// <param name="strPath">實(shí)體類存放路徑</param>
/// <param name="strNameSpace">命名空間</param>
/// <param name="lstTableNames">生產(chǎn)指定的表</param>
/// <param name="strInterface">實(shí)現(xiàn)接口</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 根據(jù)實(shí)體類生成數(shù)據(jù)庫(kù)表
/// <summary>
/// 功能描述:根據(jù)實(shí)體類生成數(shù)據(jù)庫(kù)表
/// 作 者:Blog.Core
/// </summary>
/// <param name="blnBackupTable">是否備份表</param>
/// <param name="lstEntitys">指定的實(shí)體</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>
/// 功能描述:根據(jù)實(shí)體類生成數(shù)據(jù)庫(kù)表
/// 作 者:Blog.Core
/// </summary>
/// <param name="blnBackupTable">是否備份表</param>
/// <param name="lstEntitys">指定的實(shí)體</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 靜態(tài)方法
/// <summary>
/// 功能描述:獲得一個(gè)DbContext
/// 作 者:Blog.Core
/// </summary>
/// <param name="blnIsAutoCloseConnection">是否自動(dòng)關(guān)閉連接(如果為false际乘,則使用接受時(shí)需要手動(dòng)關(guān)閉Db)</param>
/// <returns>返回值</returns>
public static DbContext GetDbContext(bool blnIsAutoCloseConnection = true)
{
return new DbContext(blnIsAutoCloseConnection);
}
/// <summary>
/// 功能描述:設(shè)置初始化參數(shù)
/// 作 者:Blog.Core
/// </summary>
/// <param name="strConnectionString">連接字符串</param>
/// <param name="enmDbType">數(shù)據(jù)庫(kù)類型</param>
public static void Init(string strConnectionString, DbType enmDbType = SqlSugar.DbType.SqlServer)
{
_connectionString = strConnectionString;
_dbType = enmDbType;
}
/// <summary>
/// 功能描述:創(chuàng)建一個(gè)鏈接配置
/// 作 者:Blog.Core
/// </summary>
/// <param name="blnIsAutoCloseConnection">是否自動(dòng)關(guān)閉連接</param>
/// <param name="blnIsShardSameThread">是否夸類事務(wù)</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>
/// 功能描述:獲取一個(gè)自定義的DB
/// 作 者:Blog.Core
/// </summary>
/// <param name="config">config</param>
/// <returns>返回值</returns>
public static SqlSugarClient GetCustomDB(ConnectionConfig config)
{
return new SqlSugarClient(config);
}
/// <summary>
/// 功能描述:獲取一個(gè)自定義的數(shù)據(jù)庫(kù)處理對(duì)象
/// 作 者: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>
/// 功能描述:獲取一個(gè)自定義的數(shù)據(jù)庫(kù)處理對(duì)象
/// 作 者: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、然后在剛剛我們實(shí)現(xiàn)那四個(gè)方法的AdvertisementRepository.cs中漂佩,重寫構(gòu)造函數(shù)脖含,編輯統(tǒng)一Sqlsugar實(shí)例方法,用到了私有屬性投蝉,為以后的單列模式做準(zhǔn)備养葵。
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層中墓拜,添加了全局的數(shù)據(jù)類型轉(zhuǎn)換方法港柜,UtilConvert,這樣就不用每次都Convert咳榜,而且也解決了為空轉(zhuǎn)換異常的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;
}
}
}
最終的倉(cāng)儲(chǔ)持久化是:
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類型,這里你可以根據(jù)你的業(yè)務(wù)需要進(jìn)行處理
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 層設(shè)計(jì)服務(wù)接口,并 Service 層實(shí)現(xiàn)
這里不細(xì)說涌韩,記得添加引用畔柔,最終的代碼是:
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);
}
}
}
都是很簡(jiǎn)單,如果昨天的Sum方法你會(huì)了臣樱,這個(gè)肯定都會(huì)靶擦。
五、Controller測(cè)試接口
實(shí)現(xiàn)工作雇毫,根據(jù)id獲取數(shù)據(jù)
這里為了調(diào)試方便玄捕,我把權(quán)限驗(yàn)證暫時(shí)注釋掉
//[Authorize(Policy ="Admin")]
然后修改我們的其中一個(gè)Get方法,根據(jù)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);
}
接下來運(yùn)行調(diào)試棚放,在我們接口文檔中蝗茁,直接點(diǎn)擊調(diào)試
得到的結(jié)果是如果梅垄,雖然是空的丧慈,但是返回結(jié)果http代碼是200,因?yàn)楸碇袥]數(shù)據(jù)嘛
六福也、結(jié)語
好啦,今天的講解就到這里攀圈,你簡(jiǎn)單的了解了什么是ORM暴凑,以及其中的SqlSugar,然后呢赘来,倉(cāng)儲(chǔ)模式的具體使用现喳,最后還有真正的連接數(shù)據(jù)庫(kù),獲取到數(shù)據(jù)撕捍,下一節(jié)中拿穴,我們繼續(xù)來解決兩大問題,來實(shí)現(xiàn)泛型倉(cāng)儲(chǔ)忧风。