EF更新少量字段需要解決兩個問題
1.動態的將需要更新的字段提取出來
2.將提取出來的字段設為更新狀態
通常更新的時候,都是根據條件將實體取出來,然后賦值字段,最后更新整個實體,所以在方法上看似是更新少量字段,其實是更新了所有字段,比較浪費性能
獲取要更新的字段列表
/// <summary> /// 獲取要更新的字段 /// </summary> /// <param name="updateAction"></param> /// <returns></returns> private List<string> GetUpdateColumns(Action<TEntity> updateAction) { List<string> modifyColumns = new List<string>(); TEntity modifyModel = new TEntity(); updateAction(modifyModel); PropertyInfo[] proArr = typeof(TEntity).GetProperties(); foreach (PropertyInfo info in proArr) { if (info.GetValue(modifyModel) != null) { modifyColumns.Add(info.Name); } } return modifyColumns; }
更新
/// <summary> /// 更新對象部分屬性 /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="predicate"></param> /// <param name="updateAction"></param> /// <returns></returns> public TResult Update(Expression<Func<TEntity, bool>> predicate, Action<TEntity> updateAction) { List<string> modifyColumns = GetUpdateColumns(updateAction); //dbContext.Configuration.AutoDetectChangesEnabled = true; var _model = dbContext.Set<TEntity>().AsNoTracking().Where(predicate).ToList(); if (_model == null) return new TResult(false, "參數為NULL"); _model.ForEach(p => { updateAction(p); dbContext.Set<TEntity>().Attach(p); var stateEntry = ((IObjectContextAdapter)dbContext).ObjectContext.ObjectStateManager.GetObjectStateEntry(p); modifyColumns.ForEach(m => stateEntry.SetModifiedProperty(m)); //dbContext.Entry<TEntity>(p).State = EntityState.Modified; }); return Save(EntityState.Modified); }
