1.前提概述
ORM物件關係對映(Object-Relational Mapping)是一種程式技術,用於實現物件導向程式語言裡不同型別系統的資料之間的轉換。從效果上說,它其實是建立了一個可在程式語言裡使用的--“虛擬物件資料庫”。ORM提供了概念性的、易於理解的模型化資料的方式。ORM方法論基於三個核心原則:
- 簡單:以最基本的形式建模資料。
- 傳達性:資料庫結構被任何人都能理解的語言文件化。
- 精確性:基於資料模型建立正確標準化的結構。---摘自百度百科 ORM把資料庫中的表對映成物件,更好的方便我們業務邏輯的處理。其底層還是基於ADO.NET。
2.建立過程
廢話不多說,還是直接看步驟
1.開啟VS2017,新建ASP.NET WEB應用程式(.NET Framework),跨平臺可以選擇.NET Core程式。
2.單擊確定,下一步在模板中選擇MVC模板。基於專案需求也可選擇其他模板。
3. 專案建立後,新建類庫(.NET Framwork)-MODEL層
4.在新建的MODEL中右擊引用選擇 管理NuGet程式包(N)...,在介面中選擇瀏覽,搜尋 linq2db 和 linq2db.SqlServer 分別安裝,如果其他資料庫則選擇相應的linq2db對應類庫。
5.安裝完成後專案會在Model層下自動建立了資料夾 LinqToDB.Templates 資料夾,開啟資料夾,將其中 CopyMe.SqlServer.tt.txt 檔案拷貝出來放在類庫下並修改名稱,字尾改為.tt 由於我連線的資料庫是XqtSaas, 所以我重新命名為XqtSaas.tt 開啟這個模板檔案 將其中的 NamespaceName = "你專案的名稱空間" LoadSqlServerMetadata("你資料庫的伺服器IP或者例項", "連線的資料庫", "連線資料庫賬號", "連線資料庫密碼");
6.配置好你的名稱空間喝資料庫資訊後,專案會自動生成你的資料庫模型,也可以每次 選中該 .tt 檔案,右擊執行自定義工具 執行完即生成了該庫下面的所有表的實體,可以展開.tt檔案,開啟.generated.cs檔案檢視生成的資料庫表模型。每次修改表模型後只要重新執行該自定義工具,即可更新對應的模型實體。
7.專案大家完成後,接下來我們來做個資料表,操作,把最基本的增刪改查實現。可以新建業務層類庫和資料層類庫
注意: 1.新建的業務層類庫 BLL和資料層類庫DAL 可以通過泛型T定義業務層基類DataBaseBLL<T>和資料層基類DataBaseDAL<T> 定義統一的公用方法
2.新建的業務層類庫 BLL和資料層類庫DAL需要引用 Linq2Db 類庫
3.每個方法需要加入 using (XqtSaasDB db = new XqtSaasDB(configName)) XqtSaasDB就是.tt檔案生成的基類
config 就是你Web.Config連線資料庫字串的name值 protected readonly string configName = "BaseDB";
7.1 DataBaseBLL<T>程式碼如下
1 using LinqToDB; 2 using LinqToDB.Data; 3 using Model; 4 using System; 5 using System.Collections.Generic; 6 using System.Linq; 7 using System.Text; 8 using System.Threading.Tasks; 9 10 11 namespace BLL 12 { 13 public class DataBaseBLL<T> where T : class 14 { 15 protected readonly string configName = "BaseDB"; 16 17 public List<T> GetList() 18 { 19 try 20 { 21 using (XqtSaasDB db = new XqtSaasDB(configName)) 22 { 23 return db.GetTable<T>().ToList(); 24 } 25 } 26 catch (Exception ex) 27 { 28 29 throw; 30 } 31 } 32 33 public T GetById(long id) 34 { 35 using (XqtSaasDB db = new XqtSaasDB(configName)) 36 { 37 var property = typeof(T).GetProperties().FirstOrDefault(_ => _.GetCustomAttributes(typeof(LinqToDB.Mapping.PrimaryKeyAttribute), false).Length > 0); 38 return db.GetTable<T>().FirstOrDefault(_ => Sql.Property<object>(_, property.Name).Equals(id)); 39 } 40 } 41 42 public bool Insert(T t) 43 { 44 using (XqtSaasDB db = new XqtSaasDB(configName)) 45 { 46 try 47 { 48 var id = db.InsertWithIdentity(t); 49 var property = typeof(T).GetProperties().FirstOrDefault(_ => _.GetCustomAttributes(typeof(LinqToDB.Mapping.PrimaryKeyAttribute), false).Length > 0); 50 if (id != null) 51 { 52 object value = Convert.ChangeType(id, property.PropertyType); 53 property.SetValue(t, value); 54 return true; 55 } 56 return false; 57 } 58 catch (Exception ex) 59 { 60 throw ex; 61 } 62 } 63 } 64 65 public void Insert(IEnumerable<T> list) 66 { 67 using (XqtSaasDB db = new XqtSaasDB(configName)) 68 { 69 db.BulkCopy(list); 70 } 71 } 72 73 74 public bool Update(T t) 75 { 76 using (XqtSaasDB db = new XqtSaasDB(configName)) 77 { 78 return db.Update(t) > 0; 79 } 80 } 81 82 public bool Delete(T t) 83 { 84 using (XqtSaasDB db = new XqtSaasDB(configName)) 85 { 86 return db.Delete(t) > 0; 87 } 88 } 89 90 public bool Delete(int Id) 91 { 92 using (XqtSaasDB db = new XqtSaasDB(configName)) 93 { 94 var property = typeof(T).GetProperties().FirstOrDefault(_ => _.GetCustomAttributes(typeof(LinqToDB.Mapping.PrimaryKeyAttribute), false).Length > 0); 95 return db.GetTable<T>().Where(_ => Sql.Property<object>(_, property.Name).Equals(Id)).Delete() > 0; 96 } 97 } 98 99 public bool Exists(Func<T, bool> predicate) 100 { 101 using (XqtSaasDB db = new XqtSaasDB(configName)) 102 { 103 return db.GetTable<T>().Where(predicate).Count() > 0; 104 } 105 } 106 } 107 }
7.2 DataBaseDAL<T> 程式碼如下
1 using LinqToDB; 2 using LinqToDB.Common; 3 using LinqToDB.Data; 4 using Model; 5 using System; 6 using System.Collections.Generic; 7 using System.Linq; 8 using System.Text; 9 using System.Threading.Tasks; 10 11 12 namespace DAL 13 { 14 public abstract class DataBaseDAL<T> where T : class 15 { 16 protected readonly string configName = "BaseDB"; 17 18 public List<T> GetList() 19 { 20 try 21 { 22 using (XqtSaasDB db = new XqtSaasDB(configName)) 23 { 24 25 return db.GetTable<T>().ToList(); 26 } 27 } 28 catch (Exception ex) 29 { 30 31 throw ex; 32 } 33 34 } 35 36 37 public T GetById(object id) 38 { 39 using (XqtSaasDB db = new XqtSaasDB(configName)) 40 { 41 var property = typeof(T).GetProperties().FirstOrDefault(_ => _.GetCustomAttributes(typeof(LinqToDB.Mapping.PrimaryKeyAttribute), false).Length > 0); 42 return db.GetTable<T>().FirstOrDefault(_ => Sql.Property<object>(_, property.Name).Equals(id)); 43 } 44 } 45 46 47 public T Excute(string sql) 48 { 49 try 50 { 51 using (XqtSaasDB db = new XqtSaasDB(configName)) 52 { 53 return db.Execute<T>(sql); 54 } 55 } 56 catch (Exception ex) 57 { 58 59 throw ex; 60 } 61 62 } 63 64 65 public List<X> Qeury<X>(string sql) 66 { 67 try 68 { 69 using (XqtSaasDB db = new XqtSaasDB(configName)) 70 { 71 return db.Query<X>(sql).ToList(); 72 } 73 } 74 catch (Exception ex) 75 { 76 77 throw ex; 78 } 79 80 } 81 82 83 public bool Insert(T t) 84 { 85 86 using (XqtSaasDB db = new XqtSaasDB(configName)) 87 { 88 try 89 { 90 var id = db.InsertWithIdentity(t); 91 var property = typeof(T).GetProperties().FirstOrDefault(_ => _.GetCustomAttributes(typeof(LinqToDB.Mapping.PrimaryKeyAttribute), false).Length > 0); 92 if (id != null) 93 { 94 object value = Convert.ChangeType(id, property.PropertyType); 95 property.SetValue(t, value); 96 return true; 97 } 98 return false; 99 } 100 catch (Exception ex) 101 { 102 return false; 103 } 104 105 106 } 107 } 108 109 110 public void Insert(IEnumerable<T> list) 111 { 112 using (XqtSaasDB db = new XqtSaasDB(configName)) 113 { 114 db.BulkCopy(list); 115 } 116 } 117 118 119 public bool Update(T t) 120 { 121 using (XqtSaasDB db = new XqtSaasDB(configName)) 122 { 123 return db.Update(t) > 0; 124 } 125 } 126 127 public bool Delete(T t) 128 { 129 using (XqtSaasDB db = new XqtSaasDB(configName)) 130 { 131 return db.Delete(t) > 0; 132 } 133 } 134 135 public bool Delete(int Id) 136 { 137 using (XqtSaasDB db = new XqtSaasDB(configName)) 138 { 139 var property = typeof(T).GetProperties().FirstOrDefault(_ => _.GetCustomAttributes(typeof(LinqToDB.Mapping.PrimaryKeyAttribute), false).Length > 0); 140 return db.GetTable<T>().Where(_ => Sql.Property<object>(_, property.Name).Equals(Id)).Delete() > 0; 141 } 142 } 143 } 144 145 public class AllowMultipleQuery : IDisposable 146 { 147 public AllowMultipleQuery() 148 { 149 Configuration.Linq.AllowMultipleQuery = true; 150 } 151 152 public void Dispose() 153 { 154 Configuration.Linq.AllowMultipleQuery = false; 155 } 156 } 157 }
8.在web層新建區域test並且新建控制器UserController 並且在User檢視中新增Index檢視 並在BLL層下新建Hr_EmpBLL 在DAL層下新建 Hr_EmpDAL 程式碼如下
8.1 Index.cshtml 檢視層
1 @{ 2 ViewBag.Title = "Index"; 3 Layout = null; 4 } 5 6 <html> 7 <head> 8 <title>運營管理平臺</title> 9 <meta charset="utf-8" /> 10 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 11 <script src="~/Scripts/jquery-1.9.1.min.js"></script> 12 <script type="text/javascript"> 13 //獲得使用者列表 14 function GetUserList() { 15 var config = { 16 url: '/User/GetUserList', 17 type: 'post', 18 dataType: 'json', 19 //data: { UserName: LoginName, Password: LoginPwd, VerCode: VerCode }, 20 success: function (result) { 21 //var list = JSON.parse(result); 22 console.info(result); 23 var html = ""; 24 $.each(result, function (index, items) { 25 html += "<li>" + items.EmpCode + ":" + items.RealName + "</li>"; 26 }); 27 $("#DivUserList").html(html); 28 }, 29 fail: function () { 30 } 31 }; 32 $.ajax(config); 33 } 34 35 //根據使用者編號獲得使用者資訊 36 function GetUserByEmpCode() { 37 var EmpCode = $("#txxEmpCode").val(); 38 var config = { 39 url: '/User/GetUserById', 40 type: 'post', 41 dataType: 'json', 42 data: { EmpCode: EmpCode }, 43 success: function (result) { 44 //var list = JSON.parse(result); 45 console.info(result); 46 var html = ""; 47 48 html += "<li>" + result.EmpCode + ":" + result.RealName + "</li>"; 49 50 $("#DivUser").html(html); 51 }, 52 fail: function () { 53 } 54 }; 55 $.ajax(config); 56 } 57 </script> 58 </head> 59 <body> 60 <input type="button" value="獲得使用者列表" onclick="GetUserList()" /> 61 <ul id="DivUserList"></ul> 62 <br /> 63 使用者編號:<input type="text" id="txxEmpCode" /> 64 <input type="button" value="根據使用者編號獲得使用者資訊" onclick="GetUserByEmpCode()" /> 65 <ul id="DivUser"></ul> 66 </body> 67 </html> 68
8.2 Hr_EmpBLL 程式碼 檢視層呼叫兩個方法 獲取使用者列表和根據使用者編號獲得單個使用者,前一個方法直接呼叫基類中方法,故不需要寫,後一個基類沒有,需要擴充套件在BLL中寫方法
1 using DAL; 2 using Model; 3 using System; 4 using System.Collections.Generic; 5 using System.Linq; 6 using System.Text; 7 using System.Threading.Tasks; 8 9 namespace BLL 10 { 11 public class Hr_EmpBLL:DataBaseBLL<HrEmp> 12 { 13 public HrEmp GetUserById(string EmpCode) 14 { 15 Hr_EmpDAL dal = new Hr_EmpDAL(); 16 return dal.GetUserById(EmpCode); 17 } 18 } 19 }
8.3 Hr_EmpDAL 程式碼 檢視層呼叫兩個方法 獲取使用者列表和根據使用者編號獲得單個使用者,前一個方法直接呼叫基類中方法,故不需要寫,後一個基類沒有,需要擴充套件在DAL中寫方法
1 using Model; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 8 namespace DAL 9 { 10 public class Hr_EmpDAL:DataBaseDAL<HrEmp> 11 { 12 public HrEmp GetUserById(string EmpCode) 13 { 14 using (XqtSaasDB db = new XqtSaasDB(configName)) 15 { 16 HrEmp query = db.HrEmps.FirstOrDefault(x => x.EmpCode.Equals(EmpCode)) ?? new HrEmp(); 17 return query; 18 } 19 } 20 } 21 }
8.4 執行效果 1.獲取使用者列表
2.通過使用者編號獲得使用者實體
3.最後結語
曾經用這個專案做了一個培訓系統,Linq2Db 用起來還是很方便的
1.通過T4模板編譯,設定好連線的資料庫及名稱空間自動生成每個表的實體,一旦表欄位更改也可重新編譯生成最新的表實體
2.Linq2Db輕量級的ORM專案搭建也比較簡單
3.在效能上要弱於ADO但相比EF要快些。
第一次寫部落格園文章,還需要慢慢學習。有什麼不對的,還望提醒。路漫漫其修遠兮,吾將上下而求索