扩展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

 

  

 

  

posted on 2013-11-09 21:00  唐扬名  阅读(922)  评论(3编辑  收藏  举报

导航