1 /// <summary> 2 /// 此类作用:数据仓库,数据基础操作 3 /// </summary> 4 /// <typeparam name="TEntity">实体</typeparam> 5 /// <remarks> 6 /// zhangqc 2016.08.08 新建 7 /// </remarks> 8 public partial class Repository<TEntity> : IRepository<TEntity>, IDisposable 9 where TEntity : class 10 { 11 /// <summary> 12 /// 数据源上下文 13 /// </summary> 14 private readonly DbContext _ctx; 15 16 /// <summary> 17 /// 数据源上下文 18 /// </summary> 19 //[Obsolete("请小心使用")] 20 public DbContext DbContext 21 { 22 get 23 { 24 return _ctx; 25 } 26 } 27 28 /// <summary> 29 /// 命令执行超时时间,单位秒,默认为300秒。 30 /// </summary> 31 public int? CommandTimeout 32 { 33 get 34 { 35 return _ctx.Database.CommandTimeout; 36 } 37 set 38 { 39 _ctx.Database.CommandTimeout = value; 40 } 41 } 42 43 /// <summary> 44 /// 返回EntitySet 45 /// </summary> 46 /// <typeparam name="T"></typeparam> 47 /// <returns></returns> 48 public EntitySet EntitySet<T>() 49 { 50 var adapter = (IObjectContextAdapter)_ctx; 51 var objectContext = adapter.ObjectContext; 52 var objectSet = objectContext.CreateObjectSet<TEntity>(); 53 return objectSet.EntitySet; 54 } 55 56 /// <summary> 57 /// 返回ObjectContext 58 /// </summary> 59 /// <returns></returns> 60 public ObjectContext ObjectContext() 61 { 62 var adapter = (IObjectContextAdapter)_ctx; 63 return adapter.ObjectContext; 64 } 65 66 67 /// <summary> 68 /// 构造方法 69 /// </summary> 70 /// <param name="session"></param> 71 public Repository(DbContext session) 72 { 73 _ctx = session; 74 _ctx.Database.CommandTimeout = 300; 75 //_objCtx = ((IObjectContextAdapter)_ctx).ObjectContext; 76 } 77 78 /// <summary> 79 /// 获取指定记录集 80 /// </summary> 81 protected DbSet<T> DbSet<T>() where T : class 82 { 83 return _ctx.Set<T>(); 84 } 85 86 #region IRepository<TEntity> Members 87 88 /// <summary> 89 /// 保存数据 90 /// </summary> 91 /// <returns>受影响的行数</returns> 92 public int Save() 93 { 94 try 95 { 96 return _ctx.SaveChanges(); 97 } 98 catch (System.Data.Entity.Validation.DbEntityValidationException ex) 99 { 100 var msg = new List<string>(); 101 foreach (var item in ex.EntityValidationErrors) 102 { 103 foreach (var err in item.ValidationErrors) 104 { 105 msg.Add(string.Format("{0} {1}", err.PropertyName, err.ErrorMessage)); 106 } 107 } 108 throw new ApplicationException(string.Join("\n", msg)); 109 } 110 } 111 112 /// <summary> 113 /// 添加当前实体 114 /// </summary> 115 /// <param name="t">实体</param> 116 /// <returns>添加后的实体</returns> 117 public TEntity Add(TEntity t) 118 { 119 return Add<TEntity>(t); 120 } 121 122 /// <summary> 123 /// 添加数据库中的实体 124 /// </summary> 125 /// <typeparam name="T">指定实体的类型</typeparam> 126 /// <param name="t">指定实体</param> 127 /// <returns>添加后的实体</returns> 128 public T Add<T>(T t) 129 where T : class 130 { 131 return DbSet<T>().Add(t); 132 } 133 134 /// <summary> 135 /// 批量添加或更新当前实体 136 /// </summary> 137 /// <param name="entity">当前实体,可多个一起传入</param> 138 public void AddOrUpdate(params TEntity[] entity) 139 { 140 DbSet<TEntity>().AddOrUpdate<TEntity>(entity); 141 } 142 143 /// <summary> 144 /// 批量添加或更新指定实体 145 /// </summary> 146 /// <typeparam name="T">指定实体类型</typeparam> 147 /// <param name="entity">指定实体,可多个一起传入</param> 148 public void AddOrUpdate<T>(params T[] entity) where T : class 149 { 150 DbSet<T>().AddOrUpdate<T>(entity); 151 } 152 153 /// <summary> 154 /// 更新当前实体 155 /// </summary> 156 /// <param name="entity">当前实体</param> 157 /// <returns>更新后的实体</returns> 158 public TEntity Update(TEntity entity) 159 { 160 return Update<TEntity>(entity); 161 } 162 163 /// <summary> 164 /// 更新指定实体 165 /// </summary> 166 /// <param name="entity">指定实体</param> 167 /// <returns>更新后的实体</returns> 168 public T Update<T>(T entity) where T : class 169 { 170 var entry = Attach(entity); 171 entry.State = EntityState.Modified; 172 return entity; 173 } 174 175 /// <summary> 176 /// 按需修改当前实体 177 /// </summary> 178 /// <param name="entity">实体对象</param> 179 /// <param name="modifiedPropertys">需要修改的字段</param> 180 /// <returns>修改状态后的实体</returns> 181 public TEntity Update(TEntity entity, List<string> modifiedPropertys) 182 { 183 return Update<TEntity>(entity, modifiedPropertys); 184 } 185 186 /// <summary> 187 /// 更新数据库中的实体 188 /// </summary> 189 /// <param name="entity">指定的实体</param> 190 /// <param name="modifiedPropertys">需要更新的字段名</param> 191 /// <returns>修改状态后的实体</returns> 192 public T Update<T>(T entity, List<string> modifiedPropertys) where T : class 193 { 194 var dbEntry = _ctx.Entry(entity); 195 dbEntry.State = EntityState.Unchanged; 196 197 if (null != modifiedPropertys) 198 { 199 modifiedPropertys.ForEach(p => 200 { 201 dbEntry.Property(p).IsModified = true; 202 }); 203 } 204 return entity; 205 } 206 207 /// <summary> 208 /// 删除当前实体 209 /// </summary> 210 /// <param name="entity">待删除的实体</param> 211 /// <returns>被删除的实体</returns> 212 public TEntity Delete(TEntity entity) 213 { 214 return Delete<TEntity>(entity); 215 } 216 217 /// <summary> 218 /// 删除当前实体列表 219 /// </summary> 220 /// <param name="list">待删除的实体列表</param> 221 public void Delete(IEnumerable<TEntity> list) 222 { 223 Delete<TEntity>(list); 224 } 225 226 /// <summary> 227 /// 删除当前实体列表 228 /// </summary> 229 /// <param name="list">待删除的实体</param> 230 public void Delete<T>(IEnumerable<T> list) where T : class 231 { 232 var l = list as IList<T> ?? list.ToList(); 233 if (l.Any()) 234 { 235 l.ForEach(p => Delete(p)); 236 } 237 } 238 /// <summary> 239 /// 240 /// </summary> 241 /// <typeparam name="T"></typeparam> 242 /// <param name="list"></param> 243 public void Delete<T>(IQueryable<T> list) where T : class 244 { 245 if (list.Any()) 246 { 247 list.ForEach(p => Delete(p)); 248 } 249 } 250 251 252 /// <summary> 253 /// 从数据库中删除指定实体 254 /// </summary> 255 /// <typeparam name="T">待删除的实体类型</typeparam> 256 /// <param name="entity">待删除的实体</param> 257 /// <returns>被删除的实体</returns> 258 public T Delete<T>(T entity) where T : class 259 { 260 Attach(entity); 261 return DbSet<T>().Remove(entity); 262 } 263 264 /// <summary> 265 /// 删除数据库中指定实体 266 /// </summary> 267 /// <param name="predicate">条件</param> 268 public void Delete(Expression<Func<TEntity, bool>> predicate) 269 { 270 var dbSet = DbSet<TEntity>(); 271 var q = dbSet.Where(predicate); 272 if (q.Any()) 273 { 274 var l = q.ToList(); 275 l.ForEach(p => dbSet.Remove(p)); 276 } 277 } 278 279 /// <summary> 280 /// 删除数据库中指定实体 281 /// </summary> 282 /// <typeparam name="T">指定实体的类型</typeparam> 283 /// <param name="predicate">条件</param> 284 public void Delete<T>(Expression<Func<T, bool>> predicate) where T : class 285 { 286 var dbSet = DbSet<T>(); 287 var q = dbSet.Where(predicate); 288 if (q.Any()) 289 { 290 var l = q.ToList(); 291 l.ForEach(p => dbSet.Remove(p)); 292 } 293 } 294 295 /// <summary> 296 /// 删除当前实体,及关联实体 297 /// </summary> 298 /// <param name="entity">当前实体</param> 299 [Obsolete("测试中,暂不使用")] 300 public void DeleteRelatedEntries(TEntity entity) 301 { 302 throw new NotImplementedException(); 303 } 304 305 /// <summary> 306 /// 按主键查询当前实体,多主键的参数需要按定义时的次序传入 307 /// </summary> 308 /// <param name="keyValues">主键值,可多个,按定义的顺序传入即可</param> 309 /// <returns>找到的实体</returns> 310 public TEntity Find(params object[] keyValues) 311 { 312 return Find<TEntity>(keyValues); 313 } 314 315 /// <summary> 316 /// 按主键查询指定实体,多主键的参数需要按定义时的次序传入 317 /// </summary> 318 /// <param name="keyValues">主键值,可多个,按定义的顺序传入即可</param> 319 /// <returns>找到的实体</returns> 320 public T Find<T>(params object[] keyValues) where T : class 321 { 322 return DbSet<T>().Find(keyValues); 323 } 324 325 /// <summary> 326 /// 根据条件查询当前实体 327 /// </summary> 328 /// <param name="predicate">按条件查询</param> 329 /// <returns>找到的实体</returns> 330 public TEntity Find(Expression<Func<TEntity, bool>> predicate) 331 { 332 return Find(DbSet<TEntity>(), predicate); 333 } 334 335 /// <summary> 336 /// 根据条件查询指定实体 337 /// </summary> 338 /// <typeparam name="T">指定的实体类型</typeparam> 339 /// <param name="predicate">按条件查询</param> 340 /// <returns>找到的实体</returns> 341 public T Find<T>(Expression<Func<T, bool>> predicate) where T : class 342 { 343 return Find(DbSet<T>(), predicate); 344 } 345 346 /// <summary> 347 /// 根据条件查询指定实体 348 /// </summary> 349 /// <typeparam name="T">指定实体类型</typeparam> 350 /// <param name="dbSet">指定记录集</param> 351 /// <param name="predicate">条件表达式</param> 352 /// <returns>符合条件的实体</returns> 353 public T Find<T>(DbQuery<T> dbSet, Expression<Func<T, bool>> predicate) where T : class 354 { 355 return dbSet.SingleOrDefault(predicate); 356 } 357 358 /// <summary> 359 /// 检查对象是否已存在 360 /// </summary> 361 /// <param name="predicate">查询条件</param> 362 /// <returns>True or False</returns> 363 public bool Any(Expression<Func<TEntity, bool>> predicate) 364 { 365 return Any(DbSet<TEntity>(), predicate); 366 } 367 368 /// <summary> 369 /// 检查对象是否已存在 370 /// </summary> 371 /// <param name="predicate">查询条件</param> 372 /// <returns>True or False</returns> 373 public bool Any<T>(Expression<Func<T, bool>> predicate) where T : class 374 { 375 return Any(DbSet<T>(), predicate); 376 } 377 378 /// <summary> 379 /// 检查对象是否已存在 380 /// </summary> 381 /// <typeparam name="T">指定实体类型</typeparam> 382 /// <param name="dbSet">指定记录集</param> 383 /// <param name="predicate">查询条件</param> 384 /// <returns>True or False</returns> 385 public bool Any<T>(DbQuery<T> dbSet, Expression<Func<T, bool>> predicate) where T : class 386 { 387 return dbSet.Any(predicate); 388 } 389 390 /// <summary> 391 /// 查当前记录集 392 /// </summary> 393 /// <returns>当前类型的所有记录数</returns> 394 public int Count() 395 { 396 return Count(DbSet<TEntity>()); 397 } 398 399 /// <summary> 400 /// 查指定记录集 401 /// </summary> 402 /// <typeparam name="T">指定实体类型</typeparam> 403 /// <returns>所有记录数</returns> 404 public int Count<T>() where T : class 405 { 406 return Count(DbSet<T>()); 407 } 408 409 /// <summary> 410 /// 查指定查询的记录集 411 /// </summary> 412 /// <typeparam name="T">指定实体类型</typeparam> 413 /// <param name="dbSet">指定记录集</param> 414 /// <returns>所有记录数</returns> 415 public int Count<T>(DbQuery<T> dbSet) where T : class 416 { 417 return dbSet.Count(); 418 } 419 420 /// <summary> 421 /// 根据条件统计当前对象 422 /// </summary> 423 /// <param name="predicate"></param> 424 /// <returns></returns> 425 public int Count(Expression<Func<TEntity, bool>> predicate) 426 { 427 return Count(DbSet<TEntity>(), predicate); 428 } 429 430 /// <summary> 431 /// 根据条件统计数据库中对象 432 /// </summary> 433 /// <typeparam name="T"></typeparam> 434 /// <param name="predicate"></param> 435 /// <returns></returns> 436 public int Count<T>(Expression<Func<T, bool>> predicate) where T : class 437 { 438 return Count(DbSet<T>(), predicate); 439 } 440 441 /// <summary> 442 /// 根据DbQuery条件统计数据库中对象 443 /// </summary> 444 /// <typeparam name="T">实体类型</typeparam> 445 /// <param name="dbSet">记录集</param> 446 /// <param name="predicate">条件</param> 447 /// <returns>符合条件的记录数</returns> 448 public int Count<T>(DbQuery<T> dbSet, Expression<Func<T, bool>> predicate) where T : class 449 { 450 return dbSet.Count(predicate); 451 } 452 453 /// <summary> 454 /// 查询实体,可对此进行后续操作。 455 /// </summary> 456 /// <returns>符合条件的结果集</returns> 457 public DbQuery<TEntity> DoQuery() 458 { 459 return DoQuery<TEntity>(); 460 } 461 462 /// <summary> 463 /// 查询实体,可对此进行后续操作。 464 /// </summary> 465 /// <typeparam name="T">指定数据集类型</typeparam> 466 /// <returns>符合条件的结果集</returns> 467 public DbQuery<T> DoQuery<T>() where T : class 468 { 469 return DbSet<T>(); 470 } 471 472 /// <summary> 473 /// 查询实体,可对此进行后续操作。 474 /// </summary> 475 /// <param name="predicate">条件表达式</param> 476 /// <returns>符合条件的结果集</returns> 477 public IQueryable<TEntity> DoQuery(Expression<Func<TEntity, bool>> predicate) 478 { 479 return DoQuery(DbSet<TEntity>(), predicate); 480 } 481 482 483 /// <summary> 484 /// 查询实体,可对此进行后续操作。 485 /// </summary> 486 /// <param name="predicate">条件表达式</param> 487 /// <returns>符合条件的结果集</returns> 488 public IEnumerable<TEntity> DoQueryFunc(Func<TEntity, bool> predicate) 489 { 490 return DoQueryFunc(DbSet<TEntity>(), predicate); 491 } 492 /// <summary> 493 /// 查询实体,可对此进行后续操作。 494 /// </summary> 495 /// <typeparam name="T">指定数据集类型</typeparam> 496 /// <param name="predicate">条件表达式</param> 497 /// <returns>符合条件的结果集</returns> 498 public IQueryable<T> DoQuery<T>(Expression<Func<T, bool>> predicate) where T : class 499 { 500 return DoQuery(DbSet<T>(), predicate); 501 } 502 503 /// <summary> 504 /// 查询实体,可对此进行后续操作。 505 /// </summary> 506 /// <typeparam name="T">指定数据集类型</typeparam> 507 /// <param name="dbSet">数据集</param> 508 /// <param name="predicate">条件表达式</param> 509 /// <returns>符合条件的结果集</returns> 510 public IQueryable<T> DoQuery<T>(DbQuery<T> dbSet, Expression<Func<T, bool>> predicate) where T : class 511 { 512 return dbSet.Where(predicate); 513 } 514 515 516 517 /// <summary> 518 /// 查询实体,可对此进行后续操作。 519 /// </summary> 520 /// <typeparam name="T"></typeparam> 521 /// <param name="dbSet"></param> 522 /// <param name="predicate"></param> 523 /// <returns></returns> 524 public IEnumerable<T> DoQueryFunc<T>(DbQuery<T> dbSet, Func<T, bool> predicate) where T : class 525 { 526 return dbSet.Where(predicate); 527 } 528 529 /// <summary> 530 /// 查询实体,可对此进行后续操作。 531 /// </summary> 532 /// <param name="predicate">条件表达式</param> 533 /// <param name="sort">排序表达式</param> 534 /// <param name="skip">Skip索引</param> 535 /// <param name="take">当前取的数量</param> 536 /// <returns>符合条件的结果集</returns> 537 public IQueryable<TEntity> DoQuery(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, object>> sort, int skip, int take) 538 { 539 return DoQuery(DbSet<TEntity>(), predicate, sort, skip, take); 540 } 541 542 /// <summary> 543 /// 查询实体,可对此进行后续操作。 544 /// </summary> 545 /// <typeparam name="T">指定数据集类型</typeparam> 546 /// <param name="dbSet">数据集</param> 547 /// <param name="predicate">条件表达式</param> 548 /// <param name="sort">排序表达式</param> 549 /// <param name="skip">Skip索引</param> 550 /// <param name="take">当前取的数量</param> 551 /// <returns>符合条件的结果集</returns> 552 public IQueryable<T> DoQuery<T>(DbQuery<T> dbSet, Expression<Func<T, bool>> predicate, Expression<Func<T, object>> sort, int skip, int take) where T : class 553 { 554 return dbSet.Skip(skip).Take(take).OrderBy(sort); 555 } 556 557 /// <summary> 558 /// 执行SQL 559 /// </summary> 560 /// <param name="sql">SQL</param> 561 /// <param name="parameters">参数</param> 562 /// <returns>受影响的语句数量</returns> 563 public int ExecuteSqlCommand(string sql, params object[] parameters) 564 { 565 return _ctx.Database.ExecuteSqlCommand(sql, parameters); 566 } 567 568 #endregion 569 570 #region IDisposable Members 571 572 /// <summary> 573 /// 释放资源 574 /// </summary> 575 public void Dispose() 576 { 577 if (null != _ctx) 578 { 579 _ctx.Dispose(); 580 } 581 } 582 583 #endregion 584 585 #region 非公有方法 586 587 /// <summary> 588 /// 附加指定实体 589 /// </summary> 590 /// <typeparam name="T">指定的实体类型</typeparam> 591 /// <param name="entity">实体数据</param> 592 /// <returns></returns> 593 protected DbEntityEntry<T> Attach<T>(T entity) where T : class 594 { 595 var entry = _ctx.Entry(entity); 596 if (entry.State == EntityState.Detached) 597 { 598 DbSet<T>().Attach(entity); 599 } 600 return entry; 601 } 602 603 /// <summary> 604 /// 获取所有主键 605 /// </summary> 606 /// <param name="entity">实体</param> 607 /// <returns>主键名列表</returns> 608 protected IEnumerable<string> GetKeyPropertyNames(object entity) 609 { 610 var objContext = ((IObjectContextAdapter)_ctx).ObjectContext; 611 return objContext.ObjectStateManager 612 .GetObjectStateEntry(entity) 613 .EntityKey 614 .EntityKeyValues 615 .Select(k => k.Key); 616 } 617 618 #endregion 619 620 }