前两篇简单谈了一些.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 ///8 /// Base class for entities 9 /// 10 ///[Serializable] 11 public abstract partial class BaseEntity 12 { 13 /// 14 /// Gets or sets the entity identifier 15 /// 16 public string Id { get; set; } 17 public virtual Nullable CreateTime { get; set; } 18 public virtual string CreatePerson { get; set; } 19 public virtual Nullable 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 IEnumerableSqlQuery (this DatabaseFacade facade, string sql, params object[] parameters) where T : class, new() 55 { 56 DataTable dt = SqlQuery(facade, sql, parameters); 57 return dt.ToEnumerable (); 58 } 59 60 public static IEnumerable ToEnumerable (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: IList 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 ///9 /// Paged list 10 /// 11 /// T 12 public class PagedList : List , IPagedList 13 { 14 /// 15 /// Ctor 16 /// 17 /// source 18 /// Page index 19 /// Page size 20 public PagedList(IQueryable 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 /// 35 /// Ctor 36 /// 37 /// source 38 /// Page index 39 /// Page size 40 public PagedList(IList 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 /// 54 /// Ctor 55 /// 56 /// source 57 /// Page index 58 /// Page size 59 /// Total count 60 public PagedList(IEnumerable 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 PagedListToPageList (this IEnumerable source, int pageIndex, int pageSize) 9 { 10 if (pageIndex < 1) 11 pageIndex = 1; 12 int TotalCount = 0; 13 List resultList = new List (); 14 resultList = source.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(); ; 15 TotalCount = source.Count(); 16 return new PagedList (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 IRepositorywhere T : BaseEntity 9 { 10 /// 11 /// 通过ID获取单个实体 12 /// 13 /// 14 /// 15 T GetById(object id); 16 /// 17 /// 插入单个实体 18 /// 19 /// 实体 20 /// 21 bool Insert(T entity); 22 /// 23 /// 插入单个实体并返回ID 24 /// 25 /// 26 /// 27 object InsertAndGetId(T entity); 28 /// 29 /// 批量插入数据集 30 /// 31 /// 数据集 32 void Insert(IEnumerable entities); 33 /// 34 /// 更新单个实体 35 /// 36 /// 实体 37 /// 38 bool Update(T entity); 39 /// 40 /// 批量更新数据集 41 /// 42 /// 43 void Update(IEnumerable entities); 44 /// 45 /// 删除单个实体 46 /// 47 /// 48 /// 49 bool Delete(T entity); 50 /// 51 /// 批量删除 52 /// 53 /// 删除的数据集 54 void Delete(IEnumerable entities); 55 /// 56 /// 通过ID删除实体 57 /// 58 /// 59 /// 60 bool DeleteById(object id); 61 /// 62 /// 通过ID(逗号分隔ID)批量删除 63 /// 64 /// 65 /// 66 bool DeleteByIds(object ids); 67 /// 68 /// 通过Id列表批量删除 69 /// 70 /// 71 /// 72 bool DeleteByIdList(List<object> list); 73 /// 74 /// 分页查询 75 /// 76 /// 当前页 77 /// 每页条数 78 /// lambda查询条件where 79 /// 排序字段 默认CreateTime 80 /// 排序方式 asc desc,默认CreateTime desc 81 /// 82 IPagedList GetListForPaging(int pageIndex, int pageSize, Expression bool>> condition = null, string orderName = null, string sortOrder = null); 83 /// 84 /// Linq连表查询专用,获取单表所有数据请使用GetList 85 /// 86 IQueryable Table { get; } 87 /// 88 /// 根据条件查找 89 /// 90 /// lambda查询条件where 91 /// 92 T GetEntity(Expression bool>> condition); 93 /// 94 /// 分页查询(Linq分页方式) 95 /// 96 /// 当前页 97 /// 页码 98 /// lambda查询条件where 99 /// <排序key:排序字段,value:bool,true-desc,false-asc 默认:CreateTime desc 100 /// 101 IPagedList GetListForPaging(int pageIndex, int pageSize, Expression bool>> condition = null, Dictionary<string, bool> sort = null); 102 /// 103 /// 执行原始SQL命令 104 /// 105 /// SQL命令 106 /// 参数 107 /// 影响的记录数 108 IEnumerable SqlQuery (string sql, params object[] parameters) where TElement : class, new(); 109 /// 110 /// 执行SqlCommand 111 /// 112 /// sql 113 /// 参数 114 /// 115 int ExecuteSqlCommand(string sql, params object[] parameters); 116 /// 117 /// 查询列表,默认返回整个表数据 118 /// 119 /// lambda查询条件where 120 /// 121 List GetList(Expression bool>> condition = null); 122 } 123 }
EFRepository:IEFRepository接口实现
1 using Microsoft.EntityFrameworkCore; 2 using System; 3 using System.Collections.Generic; 4 using System.Data; 5 using System.Linq; 6 using System.Linq.Expressions; 7 using System.Reflection; 8 using Tools.Cache; 9 10 namespace Data 11 { 12 public class EFRepository: IRepository where T : BaseEntity 13 { 14 private DbContext _context; 15 private DbSet _entities; 16 private IStaticCacheManager _cacheManager; 17 public EFRepository(DbContext context, IStaticCacheManager cacheManager) 18 { 19 this._context = context; 20 _cacheManager = cacheManager; 21 } 22 23 private DbSet Entities 24 { 25 get 26 { 27 if (_entities == null) 28 { 29 _entities = this._context.Set (); 30 } 31 return _entities; 32 } 33 } 34 /// 35 /// Linq连表查询专用,获取单表所有数据请使用GetList 36 /// 37 public virtual IQueryable Table 38 { 39 get { 40 return this.Entities; 41 } 42 } 43 /// 44 /// 通过ID获取单个实体 45 /// 46 /// 47 /// 48 public virtual T GetById(object id) 49 { 50 var cacheKey = typeof(T).Name+".GetById."+id; 51 return _cacheManager.Get(cacheKey, ()=>this.Entities.Find(id)); 52 } 53 /// 54 /// 插入单个实体 55 /// 56 /// 实体 57 /// 58 public virtual bool Insert(T entity) 59 { 60 if (entity == null) 61 throw new ArgumentNullException(nameof(entity)); 62 63 try 64 { 65 Entities.Add(entity); 66 _context.SaveChanges(); 67 var cacheContain = typeof(T).Name; 68 _cacheManager.RemoveByContain(cacheContain); 69 } 70 catch (DbUpdateException exception) 71 { 72 //ensure that the detailed error text is saved in the Log 73 throw new Exception(GetFullErrorTextAndRollbackEntityChanges(exception), exception); 74 } 75 return true; 76 } 77 /// 78 /// 插入单个实体并返回ID 79 /// 80 /// 81 /// 82 public virtual object InsertAndGetId(T entity) 83 { 84 if (entity == null) 85 throw new ArgumentNullException(nameof(entity)); 86 try 87 { 88 this.Entities.Add(entity); 89 this._context.SaveChanges(); 90 var cacheContain = typeof(T).Name; 91 _cacheManager.RemoveByContain(cacheContain); 92 } 93 catch (DbUpdateException exception) 94 { 95 //ensure that the detailed error text is saved in the Log 96 throw new Exception(GetFullErrorTextAndRollbackEntityChanges(exception), exception); 97 } 98 return entity.Id; 99 } 100 /// 101 /// 批量插入数据集 102 /// 103 /// 数据集 104 public virtual void Insert(IEnumerable entities) 105 { 106 if (entities == null) 107 throw new ArgumentNullException(nameof(entities)); 108 109 try 110 { 111 Entities.AddRange(entities); 112 _context.SaveChanges(); 113 var cacheContain = typeof(T).Name; 114 _cacheManager.RemoveByContain(cacheContain); 115 } 116 catch (DbUpdateException exception) 117 { 118 //ensure that the detailed error text is saved in the Log 119 throw new Exception(GetFullErrorTextAndRollbackEntityChanges(exception), exception); 120 } 121 } 122 /// 123 /// 更新单个实体 124 /// 125 /// 实体 126 /// 127 public virtual bool Update(T entity) 128 { 129 if (entity == null) 130 throw new ArgumentNullException(nameof(entity)); 131 try 132 { 133 this._context.Set ().Attach(entity); 134 Type _type = typeof(T); 135 PropertyInfo[] _properties = _type.GetProperties(); 136 var entry = _context.Entry(entity); 137 foreach (PropertyInfo item in _properties) 138 { 139 if ("Id" == item.Name || "CreateTime" == item.Name || "CreatePerson" == item.Name) 140 { 141 continue; 142 } 143 144 entry.Property(item.Name).IsModified = true; 145 } 146 this._context.SaveChanges(); 147 var cacheContain = typeof(T).Name; 148 _cacheManager.RemoveByContain(cacheContain); 149 } 150 catch (DbUpdateException exception) 151 { 152 //ensure that the detailed error text is saved in the Log 153 throw new Exception(GetFullErrorTextAndRollbackEntityChanges(exception), exception); 154 } 155 return true; 156 } 157 /// 158 /// 批量更新数据集 159 /// 160 /// 161 public virtual void Update(IEnumerable entities) 162 { 163 if (entities == null) 164 throw new ArgumentNullException(nameof(entities)); 165 166 try 167 { 168 // Entities.UpdateRange(entities); 169 this._context.Set ().AttachRange(entities); 170 foreach (var entity in entities) 171 { 172 Type _type = typeof(T); 173 PropertyInfo[] _properties = _type.GetProperties(); 174 var entry = _context.Entry(entity); 175 foreach (PropertyInfo item in _properties) 176 { 177 if ("Id" == item.Name || "CreateTime" == item.Name || "CreatePerson" == item.Name) 178 { 179 continue; 180 } 181 182 entry.Property(item.Name).IsModified = true; 183 } 184 } 185 186 _context.SaveChanges(); 187 var cacheContain = typeof(T).Name; 188 _cacheManager.RemoveByContain(cacheContain); 189 } 190 catch (DbUpdateException exception) 191 { 192 //ensure that the detailed error text is saved in the Log 193 throw new Exception(GetFullErrorTextAndRollbackEntityChanges(exception), exception); 194 } 195 } 196 /// 197 /// 删除单个实体 198 /// 199 /// 200 /// 201 public virtual bool Delete(T entity) 202 { 203 if (entity == null) 204 throw new ArgumentNullException(nameof(entity)); 205 206 try 207 { 208 Entities.Remove(entity); 209 _context.SaveChanges(); 210 var cacheContain = typeof(T).Name; 211 _cacheManager.RemoveByContain(cacheContain); 212 } 213 catch (DbUpdateException exception) 214 { 215 //ensure that the detailed error text is saved in the Log 216 throw new Exception(GetFullErrorTextAndRollbackEntityChanges(exception), exception); 217 } 218 return true; 219 } 220 /// 221 /// 批量删除 222 /// 223 /// 删除的数据集 224 public virtual void Delete(IEnumerable entities) 225 { 226 if (entities == null) 227 throw new ArgumentNullException(nameof(entities)); 228 229 try 230 { 231 Entities.RemoveRange(entities); 232 _context.SaveChanges(); 233 var cacheContain = typeof(T).Name; 234 _cacheManager.RemoveByContain(cacheContain); 235 } 236 catch (DbUpdateException exception) 237 { 238 //ensure that the detailed error text is saved in the Log 239 throw new Exception(GetFullErrorTextAndRollbackEntityChanges(exception), exception); 240 } 241 } 242 /// 243 /// 通过ID删除实体 244 /// 245 /// 246 /// 247 public virtual bool DeleteById(object id) 248 { 249 try 250 { 251 var item = this.Entities.Find(id); 252 if (item == null) 253 { 254 return false; 255 } 256 this.Entities.Remove(item); 257 this._context.SaveChanges(); 258 var cacheContain = typeof(T).Name; 259 _cacheManager.RemoveByContain(cacheContain); 260 } 261 catch (DbUpdateException exception) 262 { 263 //ensure that the detailed error text is saved in the Log 264 throw new Exception(GetFullErrorTextAndRollbackEntityChanges(exception), exception); 265 } 266 return true; 267 } 268 /// 269 /// 通过ID(逗号分隔ID)批量删除 270 /// 271 /// 272 /// 273 public virtual bool DeleteByIds(object ids) 274 { 275 try 276 { 277 var idArray = ids.ToString().Split(','); 278 for (int i = 0; i < idArray.Length; i++) 279 { 280 var item = this.Entities.Find(idArray[i]); 281 if (item == null) 282 { 283 continue; 284 } 285 this.Entities.Remove(item); 286 } 287 this._context.SaveChanges(); 288 var cacheContain = typeof(T).Name; 289 _cacheManager.RemoveByContain(cacheContain); 290 } 291 catch (DbUpdateException exception) 292 { 293 //ensure that the detailed error text is saved in the Log 294 throw new Exception(GetFullErrorTextAndRollbackEntityChanges(exception), exception); 295 } 296 return true; 297 } 298 /// 299 /// 通过Id列表批量删除 300 /// 301 /// 302 /// 303 public virtual bool DeleteByIdList(List<object> list) 304 { 305 try 306 { 307 for (int i = 0; i < list.Count; i++) 308 { 309 var item = this.Entities.Find(list[i]); 310 if (item == null) 311 { 312 continue; 313 } 314 this.Entities.Remove(item); 315 } 316 this._context.SaveChanges(); 317 var cacheContain = typeof(T).Name; 318 _cacheManager.RemoveByContain(cacheContain); 319 } 320 catch (DbUpdateException exception) 321 { 322 //ensure that the detailed error text is saved in the Log 323 throw new Exception(GetFullErrorTextAndRollbackEntityChanges(exception), exception); 324 } 325 return true; 326 } 327 328 /// 329 /// 根据条件查找 330 /// 331 /// lambda查询条件where 332 /// 333 public virtual T GetEntity(Expression bool>> condition) 334 { 335 var cacheKey = typeof(T) + "GetSingleOrDefault.Condition."+ condition.ToString(); 336 return _cacheManager.Get(cacheKey,()=>this.Entities.Where(condition).SingleOrDefault()); 337 } 338 /// 339 /// 分页查询(Linq分页方式) 340 /// 341 /// 当前页 342 /// 页码 343 /// lambda查询条件where 344 /// 排序key:排序字段,value:bool,true-desc,false-asc,默认:CreateTime desc 345 /// 346 public virtual IPagedList GetListForPaging(int pageIndex, int pageSize, Expression bool>> condition = null, Dictionary<string, bool> sort = null) 347 { 348 if (pageIndex < 1) 349 pageIndex = 1; 350 var cacheKey = typeof(T).Name; 351 cacheKey = cacheKey + ".GetList"; 352 List data = null; 353 354 if (condition != null) 355 { 356 cacheKey = cacheKey+ ".Condition." + condition.ToString(); 357 } 358 359 data = _cacheManager.Get >(cacheKey); 360 361 if(data != null) 362 { 363 if (sort != null) 364 { 365 foreach (var item in sort) 366 { 367 data = data.AsQueryable().OrderBy(item.Key, item.Value).ToList(); 368 } 369 } 370 else 371 { 372 data = data.AsQueryable().OrderByDescending(x => x.CreateTime).ToList(); 373 } 374 } 375 else 376 { 377 if(condition!=null) 378 { 379 data = this.Entities.Where(condition).ToList(); 380 } 381 else 382 { 383 data = this.Entities.ToList(); 384 } 385 _cacheManager.Set(cacheKey, data, 60); 386 387 data = data.AsQueryable().OrderByDescending(x => x.CreateTime).ToList();//无缓存默认返回排序后数据 388 } 389 390 return new PagedList
(data, pageIndex, pageSize); 391 } 392 393 /// 394 /// 执行原始SQL命令 395 /// 396 /// SQL命令 397 /// 参数 398 /// 影响的记录数 399 public virtual IEnumerable SqlQuery (string sql, params object[] parameters) where TElement : class, new() 400 { 401 DataTable dt = this._context.Database.SqlQuery(sql, parameters); 402 return dt.ToEnumerable (); 403 404 } 405 /// 406 /// 分页查询 407 /// 408 /// 当前页 409 /// 每页条数 410 /// lambda查询条件where 411 /// 排序字段 默认CreateTime 412 /// 排序方式 asc desc,默认CreateTime desc 413 /// 414 public virtual IPagedList GetListForPaging(int pageIndex, int pageSize, Expression bool>> condition = null, string orderName = null, string sortOrder = null) 415 { 416 var cachekey = typeof(T).Name; 417 if (pageIndex < 1) 418 pageIndex = 1; 419 if (orderName == null) 420 { 421 orderName = "CreateTime"; 422 } 423 bool isDesc = true; 424 if(sortOrder!=null&&sortOrder.ToLower() == "asc") 425 { 426 isDesc = false; 427 } 428 429 cachekey = cachekey + ".GetList"; 430 431 if(condition!=null) 432 { 433 cachekey = cachekey + ".Condition." + condition.ToString(); 434 } 435 436 List resultList = null; 437 438 var cacheData = _cacheManager.Get >(cachekey); 439 if (cacheData != null) 440 { 441 resultList = cacheData.AsQueryable().OrderBy(orderName, isDesc).ToList(); 442 } 443 else 444 { 445 if (condition == null) 446 { 447 resultList = Entities.ToList(); 448 } 449 else 450 { 451 resultList = Entities.Where(condition).ToList(); 452 } 453 _cacheManager.Set(cachekey, resultList, 60); 454 } 455 456 return new PagedList
(resultList, pageIndex, pageSize); 457 } 458 /// 459 /// 执行SqlCommand 460 /// 461 /// sql 462 /// 参数 463 /// 464 public virtual int ExecuteSqlCommand(string sql, params object[] parameters) 465 { 466 var result = this._context.Database.ExecuteSqlCommand(sql, parameters); 467 return result; 468 } 469 /// 470 /// 查询列表,默认返回整个表数据 471 /// 472 /// lambda查询条件where 473 /// 474 public virtual List GetList(Expression bool>> condition = null) 475 { 476 var cacheKey = typeof(T).Name+ ".GetList"; 477 List entities = null; 478 if (condition != null) 479 { 480 cacheKey = cacheKey + ".Condition." + condition.ToString(); 481 entities = _cacheManager.Get(cacheKey,()=>this.Entities.Where(condition).ToList()); 482 } 483 else 484 { 485 entities = _cacheManager.Get(cacheKey,()=>this.Entities.ToList()); 486 } 487 return entities; 488 } 489 #region Utilities 490 491 /// 492 /// Rollback of entity changes and return full error message 493 /// 494 /// Exception 495 /// Error message 496 protected string GetFullErrorTextAndRollbackEntityChanges(DbUpdateException exception) 497 { 498 //rollback entity changes 499 if (_context is DbContext dbContext) 500 { 501 var entries = dbContext.ChangeTracker.Entries() 502 .Where(e => e.State == EntityState.Added || e.State == EntityState.Modified).ToList(); 503 504 entries.ForEach(entry => 505 { 506 try 507 { 508 entry.State = EntityState.Unchanged; 509 } 510 catch (InvalidOperationException) 511 { 512 // ignored 513 } 514 }); 515 } 516 517 try 518 { 519 _context.SaveChanges(); 520 return exception.ToString(); 521 } 522 catch (Exception ex) 523 { 524 //if after the rollback of changes the context is still not saving, 525 //return the full text of the exception that occurred when saving 526 return ex.ToString(); 527 } 528 } 529 530 #endregion 531 532 } 533 } 534 public static class QueryableExtensions 535 { 536 public static IQueryable OrderBy (this IQueryable queryable, string propertyName) 537 { 538 return QueryableHelper .OrderBy(queryable, propertyName, false); 539 } 540 public static IQueryable OrderBy (this IQueryable queryable, string propertyName, bool desc) 541 { 542 return QueryableHelper .OrderBy(queryable, propertyName, desc); 543 } 544 static class QueryableHelper 545 { 546 private static Dictionary<string, LambdaExpression> cache = new Dictionary<string, LambdaExpression>(); 547 public static IQueryable OrderBy(IQueryable queryable, string propertyName, bool desc) 548 { 549 dynamic keySelector = GetLambdaExpression(propertyName); 550 return desc ? Queryable.OrderByDescending(queryable, keySelector) : Queryable.OrderBy(queryable, keySelector); 551 } 552 private static LambdaExpression GetLambdaExpression(string propertyName) 553 { 554 if (cache.ContainsKey(propertyName)) return cache[propertyName]; 555 var param = Expression.Parameter(typeof(T)); 556 var body = Expression.Property(param, propertyName); 557 var keySelector = Expression.Lambda(body, param); 558 cache[propertyName] = keySelector; 559 return keySelector; 560 } 561 } 562 }
_cacheManager下篇我们讲到缓存管理的时候再来讲,包括依赖注入也放到下篇,今天就先到这里了!