你的位置:首页 > ASP.net教程

[ASP.net教程]即使用ADO.NET,也要轻量级动态生成更新SQL


不管出于什么原因,有时候框架人员摒弃了NH或EF,而使用原生数据库访问对象。

为了优美的编程,用上我写的轻量级动态生成更新SQL扩展方法吧

还记得在EF中只更新修改过的字段时,我们这么写:

            var e = db.Entry(d);            e.State = EntityState.Unchanged;            d.UploadTime = DateTime.Now;            e.Property("UploadTime").IsModified = true;            db.SaveChanges();

目的是,使生成的更新SQL只更新UploadTime字段,否则会更新所有字段,那么就需要先查询一遍再更新。
既然提到数据仓储,我们更新一个实体在数据层最好只有一个方法,但是一个更新的SQL能满足要求吗?

出于以上目的,我写了这样的轻量级扩展方法:

  public static class SqlStringEx  {    /// <summary>    /// 根据实体模型的赋值情况,动态生成更新SQL。避免要先获取再保存,或者避免按需写多个更新SQL    /// </summary>    /// <typeparam name="T"></typeparam>    /// <param name="t"></param>    /// <param name="tableName">数据表名称</param>    /// <param name="conditionColumnName">更新时条件列名称,该列名需包含在parameters中</param>    /// <param name="parameters"></param>    /// <returns></returns>    public static string GenerateUpdateSql<T>(this T t, string tableName, string conditionColumnName, out List<SqlParameter> parameters)      where T : new()    {      parameters = new List<SqlParameter>();      StringBuilder res = new StringBuilder();      res.AppendFormat("update {0} set ", tableName);      var props = t.GetType().GetProperties();      string wherePart = null;      foreach (PropertyInfo item in props)      {        var propVal = item.GetValue(t, null);        var hasValue = propVal != null && !propVal.Equals(0);        if (hasValue)        {          var filedname = item.GetFieldName();          parameters.Add(new SqlParameter { Value = propVal, ParameterName = filedname });          if (filedname.Equals(conditionColumnName.ToLower()))          {            wherePart = string.Format(" where {0}=@{0} ", filedname);          }          else          {            res.AppendFormat(" {0}=@{0} ,", filedname);          }        }      }      res.Remove(res.Length - 1, 1);      res.Append(wherePart);      return res.ToString();    }  }

其中的GetFieldName()方法见上一篇

有了这个方法,数据层一个实体就只需要一个更新的方法,也不需要自己去拼接更新的SQL了。

            List<SqlParameter> parameters =null;      var saveSql = model.GenerateUpdateSql("TableName", "ID", out parameters);

注意,model的属性的默认值分两种,值类型默认值为0,引用类型和非空值类型的默认值是null,当model属性的值不是默认值的时候会参与值的更新
saveSql就是我们要更新的SQL,parameters是对应更新的参数。ID参数也可以是别的列,但在model中作为条件的列的值不能为默认值。

有没有很方便,欢迎抛砖。

虽然重复造轮子,但方便性是不是可以弥补一切。

性能要求高的,请慎重考虑,因为内部使用了反射。