扩展entityframework.extended使之支持整个实体类更新
第一次写博客,写得不好,多包涵!
用过entityframework.extended都知道,更新的时候如db.Users.Update(p=>p.Id, u =>
new
User {FirstName =
"newfirstname"
})这样用,第一个是条件,第二个参数是更新值,现在问题是,在web开发的时候,如传过来是一个对象实体User,比如修改用户时,按照这样的写法,这个User有多少个字段,那就得一个一个列出来,要是不多的话,也没多大关系,要是多的话,那就相当麻烦,而且要是User对象以后又新增了字段或者删除的话,那就得改源代码.
如下面代码,MVC开发
[HttpPost]
public ActionResult Edit(User model)
{
if (ModelState.IsValid)
{
model.ModifyBy = "admin";
model.ModifyTime = DateTime.Now;
db.Users.Update(p => p.Id == model.Id, p => new User {MembershipCard=model.MembershipCard,QQ=model.QQ });
return Redirect("Index");
}
return View();
}
假定现在User对象只有3个字段,Id,MembershipCard和QQ,这样用完全没问题,如果有一天要加个电话号码字段,前台显示页面肯定是要加个电话号码输入的,
后台代码就得改成
db.Users.Update(p => p.Id == model.Id, p => new User {MembershipCard=model.MembershipCard,QQ=model.QQ,Cellphone=model.Cellphone });
改起来很麻烦,而且字段多的话,一大堆,看起来也不简洁,
我们可不可以这样呢,
db.Users.Update(p => p.Id == model.Id, p =>model);
答案是可以的,只不过要扩展entityframework.extended中的EntityFramework.Extended类库中Extensions目录下BatchExtensions.cs文件(public static int Update<TEntity>(this IQueryable<TEntity> source,Expression<Func<TEntity, bool>> filterExpression,Expression<Func<TEntity, TEntity>> updateExpression)where TEntity : class)方法,
代码如下
if (source == null) throw new ArgumentNullException("source"); if (filterExpression == null) throw new ArgumentNullException("filterExpression"); #region 这段是新增代码
//唐扬名:扩展Update方法,使以支持db.Carriers.Update(p => p.Id == 1, p => model); Expression setExpr = updateExpression.Body; if (setExpr.Type == typeof(TEntity) && !(setExpr is NewExpression)) { IEnumerable<ParameterExpression> parameters = updateExpression.Parameters; TEntity t = (TEntity)Expression.Lambda(setExpr).Compile().DynamicInvoke(); var newe = Expression.New(typeof(TEntity)); var property = t.GetType().GetProperties(); List<MemberBinding> list = new List<MemberBinding>(); foreach (var item in property) {
//自动增长的值不能更新 var idenditi = item.GetCustomAttributes(typeof(DatabaseGeneratedAttribute), false); if (idenditi.Length > 0 && ((DatabaseGeneratedAttribute)(idenditi[0])).DatabaseGeneratedOption == DatabaseGeneratedOption.Identity) { continue; }
string name = item.Name; object value = item.GetValue(t, null); ConstantExpression constant = Expression.Constant(value, item.PropertyType); var member = Expression.Bind(typeof(TEntity).GetProperty(name), constant); list.Add(member); }
#endregion
Expression body = Expression.MemberInit(newe, list.ToArray()); LambdaExpression expression = Expression.Lambda(body, parameters); updateExpression = (Expression<Func<TEntity, TEntity>>)expression; } return source.Where(filterExpression).Update(updateExpression);
当然你还可以继续扩展这个方法,比如更新的时候实体类中的创建人,创建时间不需要更新,可以自定义一个Attribute,在判断如果就这个Attribute的话,就跳过.
写到这里,有不懂的话,QQ联系14467576