EF架构~一个规范,两个实现

回到目录

在EF环境里,我们的数据上下文对象通常是有两个版本,一个是DbContext对象,另一个是ObjectContext,个人觉得前者是轻量级的,对于code first模式中使用比较多,而后者是原生态的,最初的EDM(entity Data Model)就是以这个为基类的,它的实现与linq to sql很类似,也是分部方法,lambda表达式等元素的产物。

看看我的一个规范,两个实现吧!

一个规范:

  1 namespace Commons.Data
  2 {
  3     /// <summary>
  4     /// data repository interface
  5     /// </summary>
  6     /// <typeparam name="T"></typeparam>
  7     public interface IRepository
  8     {
  9         /// <summary>
 10         /// 添加
 11         /// </summary>
 12         /// <param name="entity"></param>
 13         void Insert<TEntity>(TEntity entity, bool isSubmit) where TEntity : class;
 14         /// <summary>
 15         /// 添加并提交
 16         /// </summary>
 17         /// <typeparam name="TEntity"></typeparam>
 18         /// <param name="entity"></param>
 19         void Insert<TEntity>(TEntity entity) where TEntity : class;
 20         /// <summary>
 21         /// 批量添加并提交
 22         /// </summary>
 23         /// <typeparam name="TEntity"></typeparam>
 24         /// <param name="entity"></param>
 25         void Insert<TEntity>(List<TEntity> list) where TEntity : class;
 26         /// <summary>
 27         /// 更新
 28         /// </summary>
 29         /// <param name="entity"></param>
 30         void Update<TEntity>(TEntity entity, bool isSubmit) where TEntity : class;
 31         /// <summary>
 32         /// 更新并提交
 33         /// </summary>
 34         /// <typeparam name="TEntity"></typeparam>
 35         /// <param name="entity"></param>
 36         void Update<TEntity>(TEntity entity) where TEntity : class;
 37         /// <summary>
 38         /// 更新列表
 39         /// </summary>
 40         /// <typeparam name="TEntity"></typeparam>
 41         /// <param name="list"></param>
 42         void Update<TEntity>(List<TEntity> list) where TEntity : class;
 43         /// <summary>
 44         /// 更新指定字段
 45         /// </summary>
 46         /// <typeparam name="T"></typeparam>
 47         /// <param name="entity"></param>
 48         void Update<TEntity>(Expression<Action<TEntity>> entity, bool isSubmit) where TEntity : class;
 49         /// <summary>
 50         /// 更新指定字段并提交
 51         /// </summary>
 52         /// <typeparam name="TEntity"></typeparam>
 53         /// <param name="entity"></param>
 54         void Update<TEntity>(Expression<Action<TEntity>> entity) where TEntity : class;
 55         /// <summary>
 56         /// 删除
 57         /// </summary>
 58         /// <param name="entity"></param>
 59         void Delete<TEntity>(TEntity entity, bool isSubmit) where TEntity : class;
 60         /// <summary>
 61         /// 删除并提交
 62         /// </summary>
 63         /// <typeparam name="TEntity"></typeparam>
 64         /// <param name="entity"></param>
 65         void Delete<TEntity>(TEntity entity) where TEntity : class;
 66         /// <summary>
 67         /// 根据主键取一个
 68         /// </summary>
 69         /// <param name="id"></param>
 70         /// <returns></returns>
 71         TEntity GetEntity<TEntity>(params object[] id) where TEntity : class;
 72         /// <summary>
 73         /// 根据条件取一个
 74         /// </summary>
 75         /// <param name="predicate"></param>
 76         /// <returns></returns>
 77         TEntity GetEntity<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class;
 78         /// <summary>
 79         /// 实体集对象的可查询结果集
 80         /// </summary>
 81         IQueryable<TEntity> GetEntities<TEntity>() where TEntity : class;
 82         /// <summary>
 83         /// 统计数量
 84         /// </summary>
 85         /// <param name="predicate"></param>
 86         /// <returns></returns>
 87         int Count<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class;
 88         /// <summary>
 89         /// 返回结果集
 90         /// </summary>
 91         /// <param name="predicate"></param>
 92         /// <returns></returns>
 93         IEnumerable<TEntity> GetEntities<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class;
 94         /// <summary>
 95         /// 带有排序的结果集
 96         /// </summary>
 97         /// <param name="predicate"></param>
 98         /// <param name="order"></param>
 99         /// <returns></returns>
100         IEnumerable<TEntity> GetEntities<TEntity>(Expression<Func<TEntity, bool>> predicate, Action<Orderable<TEntity>> order) where TEntity : class;
101         /// <summary>
102         /// 带分页和排序的结果集
103         /// </summary>
104         /// <param name="predicate"></param>
105         /// <param name="order"></param>
106         /// <param name="skip"></param>
107         /// <param name="count"></param>
108         /// <returns></returns>
109         IEnumerable<TEntity> GetEntities<TEntity>(Expression<Func<TEntity, bool>> predicate, Action<Orderable<TEntity>> order, int skip, int count) where TEntity : class;
110 
111     }
112 }

两个实现:

一 DbContext作为基类的实现:

  1 namespace Commons.Data
  2 {
  3     /// <summary>
  4     /// EF数据结构实现
  5     /// </summary>
  6     /// <typeparam name="T"></typeparam>
  7     public abstract class RepositoryBase : IRepository
  8     {
  9         #region Properties
 10         /// <summary>
 11         /// 日志对象
 12         /// </summary>
 13         public VLog.IVLog _iVlog { get; set; }
 14         /// <summary>
 15         /// 数据上下文,对子类公开
 16         /// </summary>
 17         protected readonly DbContext _db;
 18         #endregion
 19 
 20         #region Constructors
 21         /// <summary>
 22         /// 通过具体子类建立DbContext对象,并提供日志对象的实现
 23         /// </summary>
 24         /// <param name="db"></param>
 25         /// <param name="logger"></param>
 26         public RepositoryBase(DbContext db, VLog.IVLog logger)
 27         {
 28             try
 29             {
 30                 _db = db;
 31                 _iVlog = logger;
 32             }
 33             catch (Exception)
 34             {
 35 
 36                 throw new Exception("EF底层数据出现问题,请检查...");
 37             }
 38 
 39         }
 40 
 41         public RepositoryBase(DbContext db)
 42             : this(db, null)
 43         {
 44 
 45         }
 46 
 47         #endregion
 48 
 49         #region IRepository<T> 成员
 50 
 51         #region Create,Update,Delete  --Virtual Methods
 52 
 53         #region 简单调用
 54         public virtual void Insert<TEntity>(TEntity entity) where TEntity : class
 55         {
 56             this.Insert(entity, true);
 57         }
 58 
 59         public void Insert<TEntity>(List<TEntity> list) where TEntity : class
 60         {
 61             BulkInsertAll<TEntity>(list);
 62         }
 63 
 64         public void Update<TEntity>(TEntity entity) where TEntity : class
 65         {
 66             this.Update<TEntity>(entity, true);
 67         }
 68 
 69         public void Update<TEntity>(List<TEntity> list) where TEntity : class
 70         {
 71             list.ForEach(entity =>
 72             {
 73                 this.Update<TEntity>(entity, false);
 74             });
 75             this.SaveChanges();
 76         }
 77 
 78         public virtual void Update<TEntity>(Expression<Action<TEntity>> entity) where TEntity : class
 79         {
 80             this.Update<TEntity>(entity, true);
 81         }
 82 
 83         public virtual void Delete<TEntity>(TEntity entity) where TEntity : class
 84         {
 85             this.Delete<TEntity>(entity, true);
 86         }
 87         #endregion
 88 
 89         #region GUID操作实现
 90         public void Insert<TEntity>(TEntity entity, bool isSubmit) where TEntity : class
 91         {
 92             //Logger.InfoLog("Create 表名:{0},内容:{1}", entity, ToJson(entity));
 93             _db.Entry<TEntity>(entity);
 94             _db.Set<TEntity>().Add(entity);
 95             if (isSubmit)
 96                 this.SaveChanges();
 97         }
 98 
 99         public void Update<TEntity>(TEntity entity, bool isSubmit) where TEntity : class
100         {
101             _db.Set<TEntity>().Attach(entity);
102             _db.Entry(entity).State = EntityState.Modified;
103             if (isSubmit)
104                 this.SaveChanges();
105         }
106 
107         public void Update<TEntity>(Expression<Action<TEntity>> entity, bool isSubmit) where TEntity : class
108         {
109             TEntity newEntity = typeof(TEntity).GetConstructor(Type.EmptyTypes).Invoke(null) as TEntity;//建立指定类型的实例
110             List<string> propertyNameList = new List<string>();
111             MemberInitExpression param = entity.Body as MemberInitExpression;
112             foreach (var item in param.Bindings)
113             {
114                 string propertyName = item.Member.Name;
115                 object propertyValue;
116                 var memberAssignment = item as MemberAssignment;
117                 if (memberAssignment.Expression.NodeType == ExpressionType.Constant)
118                 {
119                     propertyValue = (memberAssignment.Expression as ConstantExpression).Value;
120                 }
121                 else
122                 {
123                     propertyValue = Expression.Lambda(memberAssignment.Expression, null).Compile().DynamicInvoke();
124                 }
125                 typeof(TEntity).GetProperty(propertyName).SetValue(newEntity, propertyValue, null);
126                 propertyNameList.Add(propertyName);
127             }
128             _db.Set<TEntity>().Attach(newEntity);
129             _db.Configuration.ValidateOnSaveEnabled = false;
130             var ObjectStateEntry = ((IObjectContextAdapter)_db).ObjectContext.ObjectStateManager.GetObjectStateEntry(newEntity);
131             propertyNameList.ForEach(x => ObjectStateEntry.SetModifiedProperty(x.Trim()));
132             if (isSubmit)
133                 this.SaveChanges();
134         }
135 
136         public void Delete<TEntity>(TEntity entity, bool isSubmit) where TEntity : class
137         {
138             _db.Set<TEntity>().Attach(entity);
139             _db.Set<TEntity>().Remove(entity);
140             if (isSubmit)
141                 this.SaveChanges();
142         }
143         #endregion
144 
145         #endregion
146 
147         #region Get --Virtual Methods
148         public virtual int Count<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class
149         {
150             return GetEntities(predicate).Count();
151         }
152 
153         public virtual TEntity GetEntity<TEntity>(params object[] id) where TEntity : class
154         {
155             return _db.Set<TEntity>().Find(id);
156         }
157         public virtual TEntity GetEntity<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class
158         {
159             return GetEntities(predicate).SingleOrDefault();
160         }
161 
162         public virtual IQueryable<TEntity> GetEntities<TEntity>() where TEntity : class
163         {
164             return _db.Set<TEntity>();
165         }
166         public virtual IEnumerable<TEntity> GetEntities<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class
167         {
168             return this.GetEntities<TEntity>().Where(predicate);
169         }
170 
171         public virtual IEnumerable<TEntity> GetEntities<TEntity>(Expression<Func<TEntity, bool>> predicate, Action<Orderable<TEntity>> order) where TEntity : class
172         {
173             var orderable = new Orderable<TEntity>(GetEntities(predicate).AsQueryable());
174             order(orderable);
175             return orderable.Queryable;
176         }
177 
178         public virtual IEnumerable<TEntity> GetEntities<TEntity>(Expression<Func<TEntity, bool>> predicate, Action<Orderable<TEntity>> order, int skip, int count) where TEntity : class
179         {
180             return GetEntities(predicate, order).Skip(skip).Take(count);
181         }
182         #endregion
183 
184         #endregion
185 
186         #region Methods
187         /// <summary>
188         /// 提交动作
189         /// 当程序中出现SaveChanges开始与数据库进行通讯
190         /// </summary>
191         protected virtual void SaveChanges()
192         {
193             try
194             {
195                 _db.SaveChanges(); //在有
196             }
197             catch (Exception ex)
198             {
199                 string Message = "error:";
200                 if (ex.InnerException == null)
201                     Message += ex.Message + ",";
202                 else if (ex.InnerException.InnerException == null)
203                     Message += ex.InnerException.Message + ",";
204                 else if (ex.InnerException.InnerException.InnerException == null)
205                     Message += ex.InnerException.InnerException.Message + ",";
206                 throw new Exception(Message);
207             }
208         }
209         /// <summary>
210         /// 批量插入
211         /// </summary>
212         /// <typeparam name="T"></typeparam>
213         /// <param name="entities"></param>
214         void BulkInsertAll<T>(IEnumerable<T> entities) where T : class
215         {
216             entities = entities.ToArray();
217 
218             string cs = _db.Database.Connection.ConnectionString;
219             var conn = new SqlConnection(cs);
220             conn.Open();
221 
222             Type t = typeof(T);
223 
224             var bulkCopy = new SqlBulkCopy(conn)
225             {
226                 DestinationTableName = string.Format("[{0}]", t.Name)
227             };
228 
229             var properties = t.GetProperties().Where(EventTypeFilter).ToArray();
230             var table = new DataTable();
231 
232             foreach (var property in properties)
233             {
234                 Type propertyType = property.PropertyType;
235                 if (propertyType.IsGenericType &&
236                     propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
237                 {
238                     propertyType = Nullable.GetUnderlyingType(propertyType);
239                 }
240 
241                 table.Columns.Add(new DataColumn(property.Name, propertyType));
242             }
243 
244             foreach (var entity in entities)
245             {
246                 table.Rows.Add(properties.Select(
247                   property => GetPropertyValue(
248                   property.GetValue(entity, null))).ToArray());
249             }
250 
251             bulkCopy.WriteToServer(table);
252             conn.Close();
253         }
254 
255         private bool EventTypeFilter(System.Reflection.PropertyInfo p)
256         {
257             var attribute = Attribute.GetCustomAttribute(p,
258                 typeof(AssociationAttribute)) as AssociationAttribute;
259 
260             if (attribute == null) return true;
261             if (attribute.IsForeignKey == false) return true;
262 
263             return false;
264         }
265 
266         private object GetPropertyValue(object o)
267         {
268             if (o == null)
269                 return DBNull.Value;
270             return o;
271         }
272         #endregion
273 
274     }
275 
276 }


二 ObjectContext作为基类的实现:

  1 namespace Commons.Data
  2 {
  3     /// <summary>
  4     /// EF数据结构实现
  5     /// </summary>
  6     /// <typeparam name="T"></typeparam>
  7     public abstract class ObjectContextRepositoryBase : IRepository
  8     {
  9         #region PropertiesObjectContext
 10         /// <summary>
 11         /// 日志对象
 12         /// </summary>
 13         public VLog.IVLog _iVlog { get; set; }
 14         /// <summary>
 15         /// 数据上下文,对子类公开
 16         /// </summary>
 17         protected readonly ObjectContext _db;
 18         #endregion
 19 
 20         #region Constructors
 21         /// <summary>
 22         /// 通过具体子类建立DbContext对象,并提供日志对象的实现
 23         /// </summary>
 24         /// <param name="db"></param>
 25         /// <param name="logger"></param>
 26         public ObjectContextRepositoryBase(ObjectContext db, VLog.IVLog logger)
 27         {
 28             try
 29             {
 30                 _db = db;
 31                 _iVlog = logger;
 32             }
 33             catch (Exception)
 34             {
 35 
 36                 throw new Exception("EF底层数据出现问题,请检查...");
 37             }
 38 
 39         }
 40 
 41         public ObjectContextRepositoryBase(ObjectContext db)
 42             : this(db, null)
 43         {
 44 
 45         }
 46 
 47         #endregion
 48 
 49         #region IRepository<T> 成员
 50 
 51         #region Create,Update,Delete  --Virtual Methods
 52 
 53         #region 简单调用
 54         public virtual void Insert<TEntity>(TEntity entity) where TEntity : class
 55         {
 56             this.Insert(entity, true);
 57         }
 58 
 59         public void Insert<TEntity>(List<TEntity> list) where TEntity : class
 60         {
 61             //  BulkInsertAll<TEntity>(list);
 62             list.ForEach(entity =>
 63             {
 64                 Insert(entity, false);
 65             });
 66             this.SaveChanges();
 67         }
 68 
 69         public void Update<TEntity>(TEntity entity) where TEntity : class
 70         {
 71             // this.Update<TEntity>(entity, true);
 72             UpdateEntity<TEntity>(entity);
 73         }
 74 
 75         public void Update<TEntity>(List<TEntity> list) where TEntity : class
 76         {
 77             list.ForEach(entity =>
 78             {
 79                 this.Update<TEntity>(entity, false);
 80             });
 81             this.SaveChanges();
 82         }
 83 
 84         public virtual void Update<TEntity>(Expression<Action<TEntity>> entity) where TEntity : class
 85         {
 86             this.Update<TEntity>(entity, true);
 87         }
 88 
 89         public virtual void Delete<TEntity>(TEntity entity) where TEntity : class
 90         {
 91             this.Delete<TEntity>(entity, true);
 92         }
 93         #endregion
 94 
 95         #region GUID操作实现
 96         public void Insert<TEntity>(TEntity entity, bool isSubmit) where TEntity : class
 97         {
 98             //Logger.InfoLog("Create 表名:{0},内容:{1}", entity, ToJson(entity));
 99             _db.CreateObjectSet<TEntity>().AddObject(entity);
100             if (isSubmit)
101                 this.SaveChanges();
102         }
103 
104         public void Update<TEntity>(TEntity entity, bool isSubmit) where TEntity : class
105         {
106             _db.Attach(entity as EntityObject);
107             _db.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified);
108             if (isSubmit)
109                 this.SaveChanges();
110         }
111 
112         public void Update<TEntity>(Expression<Action<TEntity>> entity, bool isSubmit) where TEntity : class
113         {
114             TEntity newEntity = typeof(TEntity).GetConstructor(Type.EmptyTypes).Invoke(null) as TEntity;//建立指定类型的实例
115             List<string> propertyNameList = new List<string>();
116             MemberInitExpression param = entity.Body as MemberInitExpression;
117             foreach (var item in param.Bindings)
118             {
119                 string propertyName = item.Member.Name;
120                 object propertyValue;
121                 var memberAssignment = item as MemberAssignment;
122                 if (memberAssignment.Expression.NodeType == ExpressionType.Constant)
123                 {
124                     propertyValue = (memberAssignment.Expression as ConstantExpression).Value;
125                 }
126                 else
127                 {
128                     propertyValue = Expression.Lambda(memberAssignment.Expression, null).Compile().DynamicInvoke();
129                 }
130                 typeof(TEntity).GetProperty(propertyName).SetValue(newEntity, propertyValue, null);
131                 propertyNameList.Add(propertyName);
132             }
133             _db.Attach(newEntity as EntityObject);
134             //  _db.Configuration.ValidateOnSaveEnabled = false;
135             var ObjectStateEntry = ((IObjectContextAdapter)_db).ObjectContext.ObjectStateManager.GetObjectStateEntry(newEntity);
136             propertyNameList.ForEach(x => ObjectStateEntry.SetModifiedProperty(x.Trim()));
137             if (isSubmit)
138                 this.SaveChanges();
139         }
140 
141         public void Delete<TEntity>(TEntity entity, bool isSubmit) where TEntity : class
142         {
143             _db.Attach(entity as EntityObject);
144             _db.ObjectStateManager.ChangeObjectState(entity, EntityState.Deleted);
145             if (isSubmit)
146                 this.SaveChanges();
147         }
148         #endregion
149 
150         #endregion
151 
152         #region Get --Virtual Methods
153         public virtual int Count<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class
154         {
155             return GetEntities(predicate).Count();
156         }
157 
158         public virtual TEntity GetEntity<TEntity>(params object[] id) where TEntity : class
159         {
160             //new NotImplementedException("this method don't implement by zzl !");
161             return null;
162         }
163         public virtual TEntity GetEntity<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class
164         {
165             return GetEntities(predicate).SingleOrDefault();
166         }
167 
168         public virtual IQueryable<TEntity> GetEntities<TEntity>() where TEntity : class
169         {
170             return _db.CreateObjectSet<TEntity>();
171         }
172         public virtual IEnumerable<TEntity> GetEntities<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class
173         {
174             return this.GetEntities<TEntity>().Where(predicate);
175         }
176 
177         public virtual IEnumerable<TEntity> GetEntities<TEntity>(Expression<Func<TEntity, bool>> predicate, Action<Orderable<TEntity>> order) where TEntity : class
178         {
179             var orderable = new Orderable<TEntity>(GetEntities(predicate).AsQueryable());
180             order(orderable);
181             return orderable.Queryable;
182         }
183 
184         public virtual IEnumerable<TEntity> GetEntities<TEntity>(Expression<Func<TEntity, bool>> predicate, Action<Orderable<TEntity>> order, int skip, int count) where TEntity : class
185         {
186             return GetEntities(predicate, order).Skip(skip).Take(count);
187         }
188         #endregion
189 
190         #endregion
191 
192         #region Methods
193         /// <summary>
194         /// 提交动作
195         /// 当程序中出现SaveChanges开始与数据库进行通讯
196         /// </summary>
197         protected virtual void SaveChanges()
198         {
199             try
200             {
201                 _db.SaveChanges(); //在有
202             }
203             catch (Exception ex)
204             {
205                 string Message = "error:";
206                 if (ex.InnerException == null)
207                     Message += ex.Message + ",";
208                 else if (ex.InnerException.InnerException == null)
209                     Message += ex.InnerException.Message + ",";
210                 else if (ex.InnerException.InnerException.InnerException == null)
211                     Message += ex.InnerException.InnerException.Message + ",";
212                 throw new Exception(Message);
213             }
214         }
215         /// <summary>
216         /// 批量插入
217         /// </summary>
218         /// <typeparam name="T"></typeparam>
219         /// <param name="entities"></param>
220         void BulkInsertAll<T>(IEnumerable<T> entities) where T : class
221         {
222             entities = entities.ToArray();
223 
224             string cs = _db.Connection.ConnectionString;
225             var conn = new SqlConnection(cs);
226             conn.Open();
227 
228             Type t = typeof(T);
229 
230             var bulkCopy = new SqlBulkCopy(conn)
231             {
232                 DestinationTableName = string.Format("[{0}]", t.Name)
233             };
234 
235             var properties = t.GetProperties().Where(EventTypeFilter).ToArray();
236             var table = new DataTable();
237 
238             foreach (var property in properties)
239             {
240                 Type propertyType = property.PropertyType;
241                 if (propertyType.IsGenericType &&
242                     propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
243                 {
244                     propertyType = Nullable.GetUnderlyingType(propertyType);
245                 }
246 
247                 table.Columns.Add(new DataColumn(property.Name, propertyType));
248             }
249 
250             foreach (var entity in entities)
251             {
252                 table.Rows.Add(properties.Select(
253                   property => GetPropertyValue(
254                   property.GetValue(entity, null))).ToArray());
255             }
256 
257             bulkCopy.WriteToServer(table);
258             conn.Close();
259         }
260 
261         private bool EventTypeFilter(System.Reflection.PropertyInfo p)
262         {
263             var attribute = Attribute.GetCustomAttribute(p,
264                 typeof(AssociationAttribute)) as AssociationAttribute;
265 
266             if (attribute == null) return true;
267             if (attribute.IsForeignKey == false) return true;
268 
269             return false;
270         }
271 
272         private object GetPropertyValue(object o)
273         {
274             if (o == null)
275                 return DBNull.Value;
276             return o;
277         }
278 
279         private void UpdateEntity<TEntity>(TEntity entity) where TEntity : class
280         {
281             Type entityType = entity.GetType();
282             var table = entityType.GetProperties().Where(i => i.PropertyType != typeof(EntityKey) && i.PropertyType != typeof(EntityState)).ToArray();
283             var primaryKeyColumns = (entity as EntityObject).GetPK();
284             List<object> arguments = new List<object>();
285             StringBuilder builder = new StringBuilder();
286 
287             foreach (var change in table)
288             {
289                 if (change == primaryKeyColumns)
290                     continue;
291 
292                 if (arguments.Count != 0)
293                     builder.Append(", ");
294 
295                 if (change.GetValue(entity, null) != null)
296                 {
297                     builder.Append(change.Name + " = {" + arguments.Count + "}");
298                     arguments.Add(change.GetValue(entity, null));
299                 }
300                 else
301                 {
302                     builder.Append(change.Name + " = NULL, ");
303                 }
304             }
305 
306             if (builder.Length == 0)
307                 return;
308 
309             builder.Insert(0, "UPDATE " + string.Format("[{0}]", entityType.Name) + " SET ");
310 
311             builder.Append(" WHERE ");
312             bool firstPrimaryKey = true;
313 
314             foreach (var primaryField in table)
315             {
316                 if (firstPrimaryKey)
317                     firstPrimaryKey = false;
318                 else
319                     builder.Append(" AND ");
320 
321                 object val = entityType.GetProperty(primaryField.Name).GetValue(entity, null);
322                 builder.Append(GetEqualStatment(primaryField.Name, arguments.Count));
323                 arguments.Add(val);
324             }
325 
326 
327 
328             try
329             {
330                 _db.ExecuteStoreCommand(builder.ToString(), arguments.ToArray());
331             }
332             catch (Exception)
333             {
334                 throw;
335             }
336         }
337 
338         private static string GetEqualStatment(string fieldName, int paramId)
339         {
340             return string.Format("{0} = {1}", fieldName, GetParamTag(paramId));
341 
342         }
343 
344         private static string GetParamTag(int paramId)
345         {
346             return "{" + paramId + "}";
347 
348         }
349         #endregion
350 
351     }
352 
353 
354     /// <summary>
355     /// ObjectContext扩展
356     /// </summary>
357     public static class ObjectContextExtension
358     {
359         /// <summary>
360         /// 得到主键
361         /// </summary>
362         public static PropertyInfo GetPK(this EntityObject value)
363         {
364             PropertyInfo[] properties = value.GetType().GetProperties();
365             foreach (PropertyInfo pI in properties)
366             {
367                 System.Object[] attributes = pI.GetCustomAttributes(true);
368                 foreach (object attribute in attributes)
369                 {
370                     if (attribute is EdmScalarPropertyAttribute)
371                     {
372                         if ((attribute as EdmScalarPropertyAttribute).EntityKeyProperty && !(attribute as EdmScalarPropertyAttribute).IsNullable)
373                             return pI;
374                     }
375 
376                 }
377             }
378             return null;
379         }
380 
381         /// <summary>
382         /// 把所有属性都标为已修改
383         /// </summary>
384         /// <param name="objectContext"></param>
385         /// <param name="item"></param>
386         public static void SetAllModified<TEntity>(this ObjectContext objectContext, TEntity item)
387         {
388             ObjectStateEntry stateEntry = objectContext.ObjectStateManager.GetObjectStateEntry(item) as ObjectStateEntry;
389             IEnumerable propertyNameList = stateEntry.CurrentValues.DataRecordInfo.FieldMetadata.Select(pn => pn.FieldType.Name);
390             foreach (string propName in propertyNameList)
391             {
392                 stateEntry.SetModifiedProperty(propName);
393             }
394             stateEntry.SetModified();
395         }
396     }
397 
398 
399 
400 }

这一个规范,两个实现,在我们实际开发过程中,如果出现问题,请及时与我联系!

大家一起讨论,共同进步!

回到目录

原文地址:https://www.cnblogs.com/lori/p/2731801.html