博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
项目使用Entity Framework用到的公共操作方法基类(Repository)及其使用 (转载)
阅读量:6160 次
发布时间:2019-06-21

本文共 18583 字,大约阅读时间需要 61 分钟。

转自:

在项目中会有很多常用的操作方法如添加、删除、修改等,而在使用EF时虽然已是ORM,但仍然会习惯性的在业务层写大量类似方法,为此,分享一个我在项目使用的公共基类,经过多次修改,已在mssql和oracle数据库项目上使用没问题。希望对使用EF开发项目的朋友有帮助,不是说写的有多好,只是为了分享,因为我在使用EF之初也一直在找这样一个类但资源很少。 欢迎拍砖,不要伤人就行。。。

以下是 Repository.cs源码 :

Repository.cs
1 using System.Collections.Generic;  2 using System.Linq;  3 using System.Linq.Expressions;  4 using System.Data.Objects;  5 using System.Data.Common;  6 using System.Transactions;  7   8 namespace System.Data.Entity  9 { 10     public class Repository
: IDisposable where TEntity : class 11 { 12 #region 私有属性 13 private ObjectContext objectContext; 14 private string entitySetName; 15 private string keyProperty = "ID"; 16 private string keyPropertyType = "Int32"; 17 #endregion 18 19 #region 公共属性 20 ///
21 /// 获得提供用于查询和使用对象形式的实体数据功能 22 /// 23 protected ObjectContext ObjContext 24 { 25 get 26 { 27 if (this.objectContext == null) 28 { 29 throw new Exception("数据库对象为空"); 30 } 31 if (this.objectContext.Connection.State == System.Data.ConnectionState.Closed) 32 { 33 this.objectContext.Connection.Open(); //如果关闭则打开 34 } 35 return this.objectContext; 36 } 37 set 38 { 39 this.objectContext = value; 40 objectContext.MetadataWorkspace.LoadFromAssembly(typeof(TEntity).Assembly); 41 } 42 } 43 ///
44 /// 实体名字 45 /// 46 public string EntitySetName 47 { 48 get { return this.entitySetName; } 49 } 50 ///
51 /// 主键字段名 52 /// 53 public string KeyProperty 54 { 55 get { return this.keyProperty; } 56 } 57 ///
58 /// 主键字段类型 59 /// 60 public string KeyPropertyType 61 { 62 get { return this.keyPropertyType; } 63 } 64 #endregion 65 66 #region objectContext 67 ///
68 /// 69 /// 70 public Repository() 71 : this(null) 72 { 73 } 74 ///
75 /// 用指定上下文构造新的实例 76 /// 77 ///
特定的上下文实例 78 public Repository(ObjectContext objectContext) 79 { 80 if (objectContext != null) //也可以构造后再指定数据库 81 { 82 this.objectContext = objectContext; //指定数据库 83 } 84 85 Type entityType = typeof(TEntity); 86 //表名 87 this.entitySetName = entityType.Name; 88 //主键 89 foreach (var prop in entityType.GetProperties()) 90 { 91 var attr = prop.GetCustomAttributes(typeof(System.Data.Objects.DataClasses.EdmScalarPropertyAttribute), false).FirstOrDefault() as System.Data.Objects.DataClasses.EdmScalarPropertyAttribute; 92 if (attr != null && attr.EntityKeyProperty) 93 { 94 this.keyProperty = prop.Name; 95 this.keyPropertyType = prop.PropertyType.Name; 96 break; 97 } 98 } 99 100 if (objectContext != null)101 {102 objectContext.MetadataWorkspace.LoadFromAssembly(typeof(TEntity).Assembly);103 }104 }105 ///
106 /// 释放对象上下文使用的资源107 /// 108 public void Dispose()109 {110 CloseObjectContext();111 }112 ///
113 /// 释放ObjectContext连接114 /// 115 public void CloseObjectContext()116 {117 if (objectContext != null )118 {119 if (objectContext.Connection.State == ConnectionState.Open)120 {121 objectContext.Connection.Close();122 }123 objectContext.Dispose();124 }125 }126 #endregion127 128 #region Find 条件表达式查询129 ///
130 /// 所有数据的查询列表131 /// 132 ///
133 public IQueryable
FindAll()134 {135 return objectContext.CreateObjectSet
().AsQueryable();136 }137 138 ///
139 /// 根据指定条件表达式得到数据查询列表140 /// 141 ///
条件表达式142 ///
143 public IQueryable
FindAll(Expression
> exp)144 {145 return objectContext.CreateObjectSet
().Where(exp);146 }147 148 ///
149 /// 根据指定条件表达式得到数据实体150 /// 151 ///
条件表达式152 ///
153 public TEntity Find(Expression
> exp)154 {155 return objectContext.CreateObjectSet
().FirstOrDefault(exp);156 }157 #endregion158 159 #region GetQuery ESQL查询160 ///
161 /// ESQL查询162 /// 163 ///
ESQL语句164 ///
参数(可选)165 ///
166 ///
可用.Execute(MergeOption.AppendOnly)执行查询
167 public ObjectQuery
GetQuery(string query, params ObjectParameter[] parameter)168 {169 return objectContext.CreateQuery
(query, parameter);170 }171 172 ///
173 /// ESQL查询列表174 /// 175 ///
ESQL语句176 ///
参数(可选)177 ///
178 ///
可用.Execute(MergeOption.AppendOnly)执行查询
179 public List
GetListByQuery(string query, params ObjectParameter[] parameter)180 {181 return objectContext.CreateQuery
(query, parameter).ToList();182 }183 ///
184 /// ESQL查询185 /// 186 ///
ESQL语句187 ///
参数(可选)188 ///
189 ///
可用.Execute(MergeOption.AppendOnly)执行查询
190 public ObjectQuery
GetObjectQuery(string query, params ObjectParameter[] parameter)191 {192 return objectContext.CreateQuery(query, parameter);193 }194 /// 195 /// ESQL查询,返回单值Object196 /// 197 /// ESQL语句198 /// 参数(可选)199 ///
200 ///
用.Execute(MergeOption.AppendOnly)查询
201 public Object GetObjectByQuery(string query, params ObjectParameter[] parameter)202 {203 return GetObjectQuery(query, parameter).Execute(MergeOption.AppendOnly).FirstOrDefault();204 }205 #endregion206 207 #region GetList 返回List列表208 /// 209 /// 所有数据列表210 /// 211 ///
212 public List
GetList()213 {214 return objectContext.CreateObjectSet
().AsQueryable().ToList();215 }216 217 ///
218 /// 根据指定表达式得到数据列表219 /// 220 ///
221 public List
GetList(Expression
> exp)222 {223 return objectContext.CreateObjectSet
().Where(exp).ToList();224 }225 226 #endregion227 228 #region Add 添加实体数据229 ///
230 /// 添加实体数据231 /// 232 ///
实体233 public int Add(TEntity entity)234 {235 objectContext.CreateObjectSet
().AddObject(entity);236 return objectContext.SaveChanges();237 }238 ///
239 /// 添加实体数据240 /// 241 ///
实体242 ///
SaveOptions:243 /// AcceptAllChangesAfterSave:把数据保存到数据库以后重置实体的状态。244 /// DetectChangesBeforeSave:把数据保存到数据库之前同步实体的状态。245 /// None:把数据保存到数据库之前,不同步实体的状态;把数据保存到数据库以后,也不重置实体的状态。246 /// 247 public int Add(TEntity entity, SaveOptions options)248 {249 objectContext.CreateObjectSet
().AddObject(entity);250 return objectContext.SaveChanges(options);251 }252 253 ///
254 /// 批量添加实体数据255 /// 256 ///
实体列表257 public int AddAll(IEnumerable
entitys)258 {259 foreach (var entity in entitys)260 {261 objectContext.CreateObjectSet
().AddObject(entity);262 }263 return objectContext.SaveChanges();264 }265 ///
266 /// 批量添加实体数据267 /// 268 ///
实体列表269 ///
SaveOptions:270 /// AcceptAllChangesAfterSave:把数据保存到数据库以后重置实体的状态。271 /// DetectChangesBeforeSave:把数据保存到数据库之前同步实体的状态。272 /// None:把数据保存到数据库之前,不同步实体的状态;把数据保存到数据库以后,也不重置实体的状态。273 /// 274 public int AddAll(IEnumerable
entitys, SaveOptions options)275 {276 var objSet = objectContext.CreateObjectSet
();277 foreach (var entity in entitys)278 {279 objSet.AddObject(entity);280 }281 return objectContext.SaveChanges(options);282 }283 #endregion284 285 #region Delete 删除实体数据286 ///
287 /// 删除实体数据288 /// 289 ///
实体290 public int Delete(TEntity entity)291 {292 objectContext.CreateObjectSet
().DeleteObject(entity);293 return objectContext.SaveChanges();294 }295 296 ///
297 /// 批量删除实体数据298 /// 299 ///
实体列表300 public int DeleteAll(IEnumerable
entitys)301 {302 if (entitys != null && entitys.Count() > 0)303 {304 foreach (var entity in entitys)305 {306 objectContext.CreateObjectSet
().DeleteObject(entity);307 }308 return objectContext.SaveChanges();309 }310 return 0;311 }312 #endregion313 314 #region Save 保存实体315 ///
316 /// 保存实体和变动317 /// 318 ///
319 public int Save()320 {321 return objectContext.SaveChanges();322 }323 ///
324 /// 保存实体和变动325 /// 326 ///
SaveOptions:327 /// AcceptAllChangesAfterSave:把数据保存到数据库以后重置实体的状态。328 /// DetectChangesBeforeSave:把数据保存到数据库之前同步实体的状态。329 /// None:把数据保存到数据库之前,不同步实体的状态;把数据保存到数据库以后,也不重置实体的状态。330 /// 331 public int Save(SaveOptions options)332 {333 return objectContext.SaveChanges(options);334 }335 ///
336 /// 保存指定的实体变动337 /// 338 ///
实体列表339 ///
340 public int Save(TEntity entity)341 {342 objectContext.AttachTo(this.entitySetName, entity);343 objectContext.SetAllModified(entity);344 return objectContext.SaveChanges();345 }346 ///
347 /// 保存指定的实体变动348 /// 349 ///
实体列表350 ///
SaveOptions:351 /// AcceptAllChangesAfterSave:把数据保存到数据库以后重置实体的状态。352 /// DetectChangesBeforeSave:把数据保存到数据库之前同步实体的状态。353 /// None:把数据保存到数据库之前,不同步实体的状态;把数据保存到数据库以后,也不重置实体的状态。354 /// 355 public int Save(TEntity entity, SaveOptions options)356 {357 objectContext.AttachTo(this.entitySetName, entity);358 objectContext.SetAllModified(entity);359 return objectContext.SaveChanges(options);360 }361 #endregion362 363 ///
364 /// 将对象或对象图附加到本实体集中的对象上下文。365 /// 366 ///
要附加的 System.Object。367 public void AttachTo(TEntity entity)368 {369 objectContext.AttachTo(this.entitySetName, entity);370 }371 ///
372 /// 将对象或对象图附加到特定实体集中的对象上下文。373 /// 374 ///
表示实体集名称,可以选择通过实体容器名称对它进行限定。375 ///
要附加的 System.Object。376 public void AttachTo(string entitySetName, TEntity entity)377 {378 objectContext.AttachTo(entitySetName, entity);379 }380 ///
381 /// 在对象具有实体键时将对象或对象图附加到对象上下文。382 /// 383 ///
要附加的对象。384 public void Attach(System.Data.Objects.DataClasses.IEntityWithKey entity)385 {386 objectContext.Attach(entity);387 }388 ///
389 /// 从对象上下文移除对象。390 /// 391 ///
要分离的对象。仅移除 entity;如果有任何相关对象受同一 System.Data.Objects.ObjectStateManager 跟踪,则不会自动分离这些对象。392 public void Detach(object entity)393 {394 objectContext.Detach(entity);395 }396 397 #region ExecuteforStore 直接执行数据源语句,如MSSQL、Oracle398 ///
399 /// 执行数据源语句(如MSSQL),返回影响的行数400 /// 401 ///
查询语句402 ///
参数(可选)403 ///
404 public int ExecuteStoreCommand(string commandText, params ObjectParameter[] parameter)405 {406 if (string.IsNullOrEmpty(commandText))407 {408 return 0;409 }410 return objectContext.ExecuteStoreCommand(commandText, parameter);411 }412 413 ///
414 /// 执行数据源查询语句(如MSSQL),获得数据查询列表415 /// 416 ///
查询语句417 ///
参数(可选)418 ///
419 public ObjectResult
ExecuteStoreQuery(string commandText, params ObjectParameter[] parameter)420 {421 return objectContext.ExecuteStoreQuery
(commandText, parameter);422 }423 424 ///
425 /// 执行数据源的函数或存储过程,返回影响的行数426 /// 427 ///
函数或存储过程428 ///
参数(可选)429 ///
430 public int ExecuteFunction(string functionName, params ObjectParameter[] parameter)431 {432 if (string.IsNullOrEmpty(functionName))433 {434 return 0;435 }436 return objectContext.ExecuteFunction(functionName, parameter);437 }438 439 ///
440 /// 执行数据源的查询函数或存储过程,获得数据查询列表441 /// 442 ///
函数或存储过程443 ///
参数(可选)444 ///
445 public ObjectResult
ExecuteFunctionQuery(string functionName, params ObjectParameter[] parameter)446 {447 return objectContext.ExecuteFunction
(functionName, parameter);448 }449 450 ///
451 /// 执行数据源语句(如MSSQL),获得得数据列表452 /// 453 ///
查询语句454 ///
参数(可选)455 ///
456 public List
GetListByStoreQuery(string commandText, params ObjectParameter[] parameter)457 {458 return objectContext.ExecuteStoreQuery
(commandText, parameter).ToList();459 }460 ///
461 /// 执行数据源的查询函数或存储过程,获得数据列表462 /// 463 ///
函数或存储过程464 ///
参数(可选)465 ///
466 public List
GetListByFunction(string functionName, params ObjectParameter[] parameter)467 {468 return objectContext.ExecuteFunction
(functionName, parameter).ToList();469 }470 #endregion471 472 #region ByID 对主键相关操作473 ///
474 /// 获得指定主键的实体475 /// 476 ///
主键值477 ///
478 public virtual TEntity GetByID(object id)479 {480 EntityKey ek = new EntityKey(objectContext.DefaultContainerName + "." + this.entitySetName, this.keyProperty, id);481 object entity = null;482 objectContext.TryGetObjectByKey(ek, out entity);483 return (entity as TEntity);484 }485 486 ///
487 /// 获得指定主键的实体列表488 /// 489 ///
用逗号(,)分隔的主键ID490 ///
491 public virtual List
GetListByIDs(string ids)492 {493 ids = SqlFilter(ids);494 if ("string".Equals(this.keyPropertyType, StringComparison.OrdinalIgnoreCase))495 {496 ids = "'" + ids.Replace(",", "','") + "'";497 }498 string query = "select value it from " + this.entitySetName + " as it where it." + this.keyProperty + " in { " + ids + "}";499 return objectContext.CreateQuery
(query).ToList();500 }501 ///
502 /// 获得指定主键的实体列表503 /// 504 ///
主键ID列表505 ///
506 public virtual List
GetListByIDs(IEnumerable
ids)507 {508 string strIDs = string.Empty;509 foreach (int id in ids)510 {511 strIDs += "," + id.ToString();512 }513 if (strIDs.Length > 1)514 {515 strIDs = strIDs.Substring(1);516 }517 return GetListByIDs(strIDs);518 }519 520 /// 521 /// 删除指定ID的实体。522 /// 注意:此处直接执行数据源语句523 /// 524 /// 用逗号(,)分隔的主键ID525 ///
526 public virtual int DeleteByIDs(string ids)527 {528 if (string.IsNullOrEmpty(ids))529 {530 return 0;531 }532 ids = SqlFilter(ids);533 if ("string".Equals(this.keyPropertyType, StringComparison.OrdinalIgnoreCase))534 {535 ids = "'" + ids.Replace(",", "','") + "'";536 }537 string sql = string.Format("delete {0} where {1} in({2})", this.entitySetName, this.keyProperty, ids);538 return ExecuteStoreCommand(sql);539 }540 541 /// 542 /// 删除指定ID组的实体543 /// 544 /// 主键ID列表545 ///
546 public virtual int DeleteByIDs(IEnumerable ids)547 {548 string strIDs = string.Empty;549 foreach (int id in ids)550 {551 strIDs += "," + id.ToString();552 }553 if (strIDs.Length > 1)554 {555 strIDs = strIDs.Substring(1);556 }557 return DeleteByIDs(strIDs);558 }559 #endregion560 561 #region 事务562 /// 563 /// TransactionScope事务处理。564 /// TransactionScopeOption 默认值为 Required。565 /// 用 .Complete() 提交事务566 /// 567 ///
返回 TransactionScope
568 public TransactionScope GetTransactionScope()569 {570 return (new TransactionScope(TransactionScopeOption.Required));571 }572 /// 573 /// TransactionScope事务处理。574 /// 用 .Complete() 提交事务575 /// 576 /// 提供用于创建事务范围的附加选项:577 /// Required:该范围需要一个事务。如果已经存在环境事务,则使用该环境事务。否则,在进入范围之前创建新的事务。这是默认值。 578 /// RequiresNew:总是为该范围创建新事务。 579 /// Suppress:环境事务上下文在创建范围时被取消。范围中的所有操作都在无环境事务上下文的情况下完成。 580 /// 581 ///
返回 TransactionScope
582 public TransactionScope GetTransactionScope(TransactionScopeOption scopeOption)583 {584 return (new TransactionScope(scopeOption));585 }586 /// 587 /// TransactionScope事务处理。588 /// 用 .Complete() 提交事务589 /// 590 /// 提供用于创建事务范围的附加选项:591 /// Required:该范围需要一个事务。如果已经存在环境事务,则使用该环境事务。否则,在进入范围之前创建新的事务。这是默认值。 592 /// RequiresNew:总是为该范围创建新事务。 593 /// Suppress:环境事务上下文在创建范围时被取消。范围中的所有操作都在无环境事务上下文的情况下完成。 594 /// 595 /// 在它之后,事务范围将超时并中止此事务。596 ///
返回 TransactionScope
597 public TransactionScope GetTransactionScope(TransactionScopeOption scopeOption, TimeSpan scopeTimeout)598 {599 return (new TransactionScope(scopeOption, scopeTimeout));600 }601 602 /// 603 /// TransactionScope事务处理。604 /// 用 .Complete() 提交事务605 /// 606 /// 要设置为环境事务(以便该范围中进行的事务性工作使用此事务)的事务。607 ///
返回 TransactionScope
608 public TransactionScope GetTransactionScope(Transaction transactionToUse)609 {610 return (new TransactionScope(transactionToUse));611 }612 /// 613 /// TransactionScope事务处理。614 /// 用 .Complete() 提交事务615 /// 616 /// 要设置为环境事务(以便该范围中进行的事务性工作使用此事务)的事务。617 /// 在它之后,事务范围将超时并中止此事务。618 ///
返回 TransactionScope
619 public TransactionScope GetTransactionScope(Transaction transactionToUse, TimeSpan scopeTimeout)620 {621 return (new TransactionScope(transactionToUse, scopeTimeout));622 }623 624 /// 625 /// TransactionScope事务处理。626 /// 用 .Complete() 提交事务627 /// 628 /// 提供用于创建事务范围的附加选项:629 /// Required:该范围需要一个事务。如果已经存在环境事务,则使用该环境事务。否则,在进入范围之前创建新的事务。这是默认值。 630 /// RequiresNew:总是为该范围创建新事务。 631 /// Suppress:环境事务上下文在创建范围时被取消。范围中的所有操作都在无环境事务上下文的情况下完成。 632 /// 633 /// 包含指定事务行为的附加信息。634 ///
返回 TransactionScope
635 public TransactionScope GetTransactionScope(TransactionScopeOption scopeOption, TransactionOptions transactionOptions)636 {637 return (new TransactionScope(scopeOption, transactionOptions));638 } 639 640 #endregion641 642 #region 辅助方法643 /// 644 /// sql注入过滤645 /// 646 /// 647 ///
648 public string SqlFilter(string sqlString)649 {650 return sqlString651 .Replace("'", "''");652 }653 #endregion654 }655 656 }

ObjectContext扩展类ObjectContextExtension.cs

ObjectContextExtension.cs
1 using System.Linq; 2 using System.Data.Objects; 3 using System.Collections; 4  5 namespace System.Data.Objects 6 { 7     ///  8     /// ObjectContext扩展 9     /// 10     public static class ObjectContextExtension11     {12         /// 13         /// 把所有属性都标为已修改14         /// 15         /// 16         /// 17         public static void SetAllModified(this ObjectContext objectContext, object item)18         {19             ObjectStateEntry stateEntry = objectContext.ObjectStateManager.GetObjectStateEntry(item) as ObjectStateEntry;20             IEnumerable propertyNameList = stateEntry.CurrentValues.DataRecordInfo.FieldMetadata.Select(pn => pn.FieldType.Name);21             foreach (string propName in propertyNameList)22             {23                 stateEntry.SetModifiedProperty(propName);24             }25             stateEntry.SetModified();26         }27     }28 }

 

使用上可以用以下结构:

1. 建一个base业务类,代码如下:

BaseService.cs
1 public class BaseService
: Repository
where TEntity : System.Data.Objects.DataClasses.EntityObject //或用class 2 { 3 public BaseService() 4 : base(new OA.Data.OAEntities())//默认数据库 5 { 6 } 7 public BaseService(System.Data.Objects.ObjectContext objContext) 8 : base(objContext) 9 {10 }11 ///
12 /// 为其它Service指定与本Service相同的ObjContext数据对象13 /// 14 ///
目标Service15 protected dynamic SameObjContext(dynamic service)16 {17 service.ObjContext = this.ObjContext;18 return service;19 }20 }

2.业务层的每个业务类都继承BaseService,如针对Department的业务层DepartmentService.cs代码:

DepartmentService.cs
1 public class DepartmentService : BaseService
2 {3 }

(完)

转载于:https://www.cnblogs.com/zcm123/archive/2013/02/20/2918398.html

你可能感兴趣的文章
阿里云专家穆轩的《杭州九年程序员之“修炼”手册》
查看>>
JQuery:deferred对象的方法
查看>>
eyoucms问答 百度权重是什么
查看>>
win10中遇到qq视频时摄像头打不开没反应的解决方法
查看>>
介绍自己的一个Android插桩热修复框架项目QuickPatch
查看>>
关于textarea的ie9的maxlength不起作用的问题,请参考如下URL解决。
查看>>
Solr Facet 查询
查看>>
C++类的继承一
查看>>
数据库分库分表(sharding)系列(五) 一种支持自由规划无须数据迁移和修改路由代码的Sharding扩容方案...
查看>>
巧用VMware Workstation的clone来制作虚拟机模板
查看>>
Spring-Mybatis MapperScannerConfigurer 取不到PropertyPlaceholderConfigurer里的值
查看>>
HP DL380G4服务器前面板指示灯的含义
查看>>
数据结构_树结构
查看>>
常用URL地址
查看>>
每天一个linux命令(19):find 命令概览
查看>>
MySQL kill操作
查看>>
windows下看端口占用
查看>>
Decommissioning a Domain Controller 降域控
查看>>
Character中的奇葩
查看>>
c++书籍推荐
查看>>