前兩篇簡單談了一些.Net Core的優勢以及機構設計的一些思路,這一篇開始,我們將從零開始搭建架構,底層我們將採用EF來訪問資料庫,所以這篇我們將貼一下EF常用操作的基類。 簡單介紹下一些類庫將要實現的功能: Business:業務實現層 Domains:實體(Model) Service:介面 ...
前兩篇簡單談了一些.Net Core的優勢以及機構設計的一些思路,這一篇開始,我們將從零開始搭建架構,底層我們將採用EF來訪問資料庫,所以這篇我們將貼一下EF常用操作的基類。
簡單介紹下一些類庫將要實現的功能:
Business:業務實現層
Domains:實體(Model)
Service:介面
Data:資料庫訪問(EF或其他)
EasyCacheing:開源緩存管理
Tools:工具類庫
其他的我們用到的時候再說;
接著說EF常用操作基類,我們將基類放在Data下,具體目錄結構如下:
BaseEntity:實體基類,基礎共有的放在這裡面:
1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 5 namespace Data 6 { 7 /// <summary> 8 /// Base class for entities 9 /// </summary> 10 ///[Serializable] 11 public abstract partial class BaseEntity 12 { 13 /// <summary> 14 /// Gets or sets the entity identifier 15 /// </summary> 16 public string Id { get; set; } 17 public virtual Nullable<DateTime> CreateTime { get; set; } 18 public virtual string CreatePerson { get; set; } 19 public virtual Nullable<DateTime> UpdateTime { get; set; } 20 public virtual string UpdatePerson { get; set; } 21 22 public BaseEntity() 23 { 24 this.Id = GetIdentifier(); 25 this.CreateTime = DateTime.Now; 26 this.UpdateTime = DateTime.Now; 27 } 28 29 private string GetIdentifier() 30 { 31 return Guid.NewGuid().ToString(); 32 } 33 34 public override bool Equals(object obj) 35 { 36 return Equals(obj as BaseEntity); 37 } 38 39 private static bool IsTransient(BaseEntity obj) 40 { 41 return obj != null && Equals(obj.Id, default(string)); 42 } 43 44 private Type GetUnproxiedType() 45 { 46 return GetType(); 47 } 48 49 public virtual bool Equals(BaseEntity other) 50 { 51 if (other == null) 52 return false; 53 54 if (ReferenceEquals(this, other)) 55 return true; 56 57 if (!IsTransient(this) && 58 !IsTransient(other) && 59 Equals(Id, other.Id)) 60 { 61 var otherType = other.GetUnproxiedType(); 62 var thisType = GetUnproxiedType(); 63 return thisType.IsAssignableFrom(otherType) || 64 otherType.IsAssignableFrom(thisType); 65 } 66 67 return false; 68 } 69 70 public static bool operator ==(BaseEntity x, BaseEntity y) 71 { 72 return Equals(x, y); 73 } 74 75 public static bool operator !=(BaseEntity x, BaseEntity y) 76 { 77 return !(x == y); 78 } 79 } 80 }
DbContextExtensions:資料庫操作擴展
1 using Microsoft.EntityFrameworkCore; 2 using Microsoft.EntityFrameworkCore.Infrastructure; 3 using System; 4 using System.Collections.Generic; 5 using System.Data; 6 using System.Data.Common; 7 using System.Data.SqlClient; 8 using System.Reflection; 9 using System.Text; 10 11 namespace Data 12 { 13 public static class DbContextExtensions 14 { 15 private static void CombineParams(ref DbCommand command, params object[] parameters) 16 { 17 if (parameters != null) 18 { 19 foreach (SqlParameter parameter in parameters) 20 { 21 if (!parameter.ParameterName.Contains("@")) 22 parameter.ParameterName = $"@{parameter.ParameterName}"; 23 command.Parameters.Add(parameter); 24 } 25 } 26 } 27 28 29 private static DbCommand CreateCommand(DatabaseFacade facade, string sql, out DbConnection dbConn, params object[] parameters) 30 { 31 DbConnection conn = facade.GetDbConnection(); 32 dbConn = conn; 33 conn.Open(); 34 DbCommand cmd = conn.CreateCommand(); 35 if (facade.IsSqlServer()) 36 { 37 cmd.CommandText = sql; 38 CombineParams(ref cmd, parameters); 39 } 40 return cmd; 41 } 42 43 public static DataTable SqlQuery(this DatabaseFacade facade, string sql, params object[] parameters) 44 { 45 DbCommand cmd = CreateCommand(facade, sql, out DbConnection conn, parameters); 46 DbDataReader reader = cmd.ExecuteReader(); 47 DataTable dt = new DataTable(); 48 dt.Load(reader); 49 reader.Close(); 50 conn.Close(); 51 return dt; 52 } 53 54 public static IEnumerable<T> SqlQuery<T>(this DatabaseFacade facade, string sql, params object[] parameters) where T : class, new() 55 { 56 DataTable dt = SqlQuery(facade, sql, parameters); 57 return dt.ToEnumerable<T>(); 58 } 59 60 public static IEnumerable<T> ToEnumerable<T>(this DataTable dt) where T : class, new() 61 { 62 PropertyInfo[] propertyInfos = typeof(T).GetProperties(); 63 T[] ts = new T[dt.Rows.Count]; 64 int i = 0; 65 foreach (DataRow row in dt.Rows) 66 { 67 T t = new T(); 68 foreach (PropertyInfo p in propertyInfos) 69 { 70 if (dt.Columns.IndexOf(p.Name) != -1 && row[p.Name] != DBNull.Value) 71 p.SetValue(t, row[p.Name], null); 72 } 73 ts[i] = t; 74 i++; 75 } 76 return ts; 77 } 78 } 79 }
IPagedList:分頁介面
1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 5 namespace Data 6 { 7 public interface IPagedList<T> : IList<T> 8 { 9 int PageIndex { get; } 10 int PageSize { get; } 11 int TotalCount { get; } 12 int TotalPages { get; } 13 bool HasPreviousPage { get; } 14 bool HasNextPage { get; } 15 } 16 }
PagedList:分頁介面的實現
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Data 7 { 8 /// <summary> 9 /// Paged list 10 /// </summary> 11 /// <typeparam name="T">T</typeparam> 12 public class PagedList<T> : List<T>, IPagedList<T> 13 { 14 /// <summary> 15 /// Ctor 16 /// </summary> 17 /// <param name="source">source</param> 18 /// <param name="pageIndex">Page index</param> 19 /// <param name="pageSize">Page size</param> 20 public PagedList(IQueryable<T> source, int pageIndex, int pageSize) 21 { 22 int total = source.Count(); 23 this.TotalCount = total; 24 this.TotalPages = total / pageSize; 25 26 if (total % pageSize > 0) 27 TotalPages++; 28 29 this.PageSize = pageSize; 30 this.PageIndex = pageIndex; 31 this.AddRange(source.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList()); 32 } 33 34 /// <summary> 35 /// Ctor 36 /// </summary> 37 /// <param name="source">source</param> 38 /// <param name="pageIndex">Page index</param> 39 /// <param name="pageSize">Page size</param> 40 public PagedList(IList<T> source, int pageIndex, int pageSize) 41 { 42 TotalCount = source.Count(); 43 TotalPages = TotalCount / pageSize; 44 45 if (TotalCount % pageSize > 0) 46 TotalPages++; 47 48 this.PageSize = pageSize; 49 this.PageIndex = pageIndex; 50 this.AddRange(source.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList()); 51 } 52 53 /// <summary> 54 /// Ctor 55 /// </summary> 56 /// <param name="source">source</param> 57 /// <param name="pageIndex">Page index</param> 58 /// <param name="pageSize">Page size</param> 59 /// <param name="totalCount">Total count</param> 60 public PagedList(IEnumerable<T> source, int pageIndex, int pageSize, int totalCount) 61 { 62 TotalCount = totalCount; 63 TotalPages = TotalCount / pageSize; 64 65 if (TotalCount % pageSize > 0) 66 TotalPages++; 67 68 this.PageSize = pageSize; 69 this.PageIndex = pageIndex; 70 this.AddRange(source); 71 } 72 73 public int PageIndex { get; private set; } 74 public int PageSize { get; private set; } 75 public int TotalCount { get; private set; } 76 public int TotalPages { get; private set; } 77 78 public bool HasPreviousPage 79 { 80 get { return (PageIndex > 0); } 81 } 82 public bool HasNextPage 83 { 84 get { return (PageIndex + 1 < TotalPages); } 85 } 86 } 87 }
IEnumerableExtensions:IEnumerable分頁的擴展
1 using System.Collections.Generic; 2 using System.Linq; 3 4 namespace Data 5 { 6 public static class IEnumerableExtensions 7 { 8 public static PagedList<TSource> ToPageList<TSource>(this IEnumerable<TSource> source, int pageIndex, int pageSize) 9 { 10 if (pageIndex < 1) 11 pageIndex = 1; 12 int TotalCount = 0; 13 List<TSource> resultList = new List<TSource>(); 14 resultList = source.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(); ; 15 TotalCount = source.Count(); 16 return new PagedList<TSource>(resultList, pageIndex, pageSize, TotalCount); 17 } 18 } 19 }
IRepository:資料庫倉庫訪問介面
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Linq.Expressions; 5 6 namespace Data 7 { 8 public interface IRepository<T> where T : BaseEntity 9 { 10 /// <summary> 11 /// 通過ID獲取單個實體 12 /// </summary> 13 /// <param name="id"></param> 14 /// <returns></returns> 15 T GetById(object id); 16 /// <summary> 17 /// 插入單個實體 18 /// </summary> 19 /// <param name="entity">實體</param> 20 /// <returns></returns> 21 bool Insert(T entity); 22 /// <summary> 23 /// 插入單個實體並返回ID 24 /// </summary> 25 /// <param name="entity"></param> 26 /// <returns></returns> 27 object InsertAndGetId(T entity); 28 /// <summary> 29 /// 批量插入數據集 30 /// </summary> 31 /// <param name="entities">數據集</param> 32 void Insert(IEnumerable<T> entities); 33 /// <summary> 34 /// 更新單個實體 35 /// </summary> 36 /// <param name="entity">實體</param> 37 /// <returns></returns> 38 bool Update(T entity); 39 /// <summary> 40 /// 批量更新數據集 41 /// </summary> 42 /// <param name="entities"></param> 43 void Update(IEnumerable<T> entities); 44 /// <summary> 45 /// 刪除單個實體 46 /// </summary> 47 /// <param name="entity"></param> 48 /// <returns></returns> 49 bool Delete(T entity); 50 /// <summary> 51 /// 批量刪除 52 /// </summary> 53 /// <param name="entities">刪除的數據集</param> 54 void Delete(IEnumerable<T> entities); 55 /// <summary> 56 /// 通過ID刪除實體 57 /// </summary> 58 /// <param name="id"></param> 59 /// <returns></returns> 60 bool DeleteById(object id); 61 /// <summary> 62 /// 通過ID(逗號分隔ID)批量刪除 63 /// </summary> 64 /// <param name="ids"></param> 65 /// <returns></returns> 66 bool DeleteByIds(object ids); 67 /// <summary> 68 /// 通過Id列表批量刪除 69 /// </summary> 70 /// <param name="list"></param> 71 /// <returns></returns> 72 bool DeleteByIdList(List<object> list); 73 /// <summary> 74 /// 分頁查詢 75 /// </summary> 76 /// <param name="pageIndex">當前頁</param> 77 /// <param name="pageSize">每頁條數</param> 78 /// <param name="condition">lambda查詢條件where</param> 79 /// <param name="orderName">排序欄位 預設CreateTime</param> 80 /// <param name="sortOrder">排序方式 asc desc,預設CreateTime desc</param> 81 /// <returns></returns> 82 IPagedList<T> GetListForPaging(int pageIndex, int pageSize, Expression<Func<T, bool>> condition = null, string orderName = null, string sortOrder = null); 83 /// <summary> 84 /// Linq連表查詢專用,獲取單表所有數據請使用GetList 85 /// </summary> 86 IQueryable<T> Table { get; } 87 /// <summary> 88 /// 根據條件查找 89 /// </summary> 90 /// <param name="condition">lambda查詢條件where</param> 91 /// <returns></returns> 92 T GetEntity(Expression<Func<T, bool>> condition); 93 /// <summary> 94 /// 分頁查詢(Linq分頁方式) 95 /// </summary> 96 /// <param name="pageIndex">當前頁</param> 97 /// <param name="pageSize">頁碼</param> 98 /// <param name="condition">lambda查詢條件where</param> 99 /// <<param name="sort">排序key:排序欄位,value:bool,true-desc,false-asc 預設:CreateTime desc</param> 100 /// <returns></returns> 101 IPagedList<T> GetListForPaging(int pageIndex, int pageSize, Expression<Func<T, bool>> condition = null, Dictionary<string, bool> sort = null); 102 /// <summary> 103 /// 執行原始SQL命令 104 /// </summary> 105 /// <param name="commandText">SQL命令</param> 106 /// <param name="parameters">參數</param> 107 /// <returns>影響的記錄數</returns> 108 IEnumerable<TElement> SqlQuery<TElement>(string sql, params object[] parameters) where TElement : class, new(); 109 /// <summary> 110 /// 執行SqlCommand 111 /// </summary> 112 /// <param name="sql">sql</param> 113 /// <param name="parameters">參數</param> 114 /// <returns></returns> 115 int ExecuteSqlCommand(string sql, params object[] parameters); 116 /// <summary> 117 /// 查詢列表,預設返回整個表數據 118 /// </summary> 119 /// <param name="condition">lambda查詢條件where</param> 120 /// <returns></returns> 121 List<T> GetList(Expression<Func<T, bool>> condition = null); 122 } 123 }
EFRepository:IEFRepository介面實現
1 using Microsoft.EntityFrameworkCore; 2 using System; 3 using System.Collections.Generic; 4 using