ORM框架学习-UPDATE数据
Update部分实现代码
public bool Update<T>(T t) where T : BaseModel { try { Type type = typeof(T); string conStr = "Server=127.0.0.1;Database=master; integrated security=SSPI"; string UpdateStr = SqlBuilder<T>.GetSql(SqlBuilder<T>.SqlType.UpdateSql); var sqlpara = type.GetProperties().Select(p => new SqlParameter("@" + p.GetMappingName(), p.GetValue(t) ?? DBNull.Value)).ToArray(); using (SqlConnection conn = new SqlConnection(conStr)) { SqlCommand cmd = new SqlCommand(UpdateStr, conn); cmd.Parameters.AddRange(sqlpara); conn.Open(); int result = cmd.ExecuteNonQuery(); return result > 0; } } catch (Exception ex) { throw new Exception(ex.Message); } }
该代码和之前的Insert和ADD代码类似,在Update这一块,主要的新点是:通过特性对更新的数据做过滤。因为在我们日常的需求中,需要对用户填写传到后台的数据做一些数据验证,检查这些数据是否符合规定,比如一些为空验证、长度限制验证。
程序入口代码如下所示
static void Main(string[] args) { SqlHelper help = new SqlHelper(); UserModel u1 = help.Query<UserModel>(1); Company com1 = help.Query<Company>(2); bool re1 = help.AddData(u1); bool re2 = help.AddData(com1); u1.Names = ""; if (!u1.Validate()) { Console.WriteLine("验证未通过!"); return; } bool re3 = help.Update(u1); }
调用数据验证的方法如图下图所示
Validate是一个泛型的方法,用来定义数据检查的,是一个扩展方法。代码实现如下所示:
public static class ValidateExtend { public static bool Validate<T>(this T t) { Type type=typeof(T); foreach (var prop in type.GetProperties()) { var val = prop.GetValue(t); if (prop.IsDefined(typeof(ThemeValidate), true)) { foreach (var item in prop.GetCustomAttributes<ThemeValidate>()) { if (!item.Validate(val)) { return false; } } } } return true; } }
如上代码所示,Validate方法是一个泛型的扩展方法,因为参数有this的存在,是一个扩展方法,所以可以直接通过对象来调用。为了便于今后扩展检查规则,我们抽象出来一个基类ThemeValidate,今后需要做验证的特性都需要继承自ThemeValidate类,ThemeValidate定义如下:
public abstract class ThemeValidate:Attribute { public abstract bool Validate(object obj); }
ThemeValidate只定义了一个抽象方法,该方法就对应子类的验证规则。下面我们来看两个ThemeValidate的子类定义
数据不能为空验证类ThemeRequireAttribute:
public class ThemeRequireAttribute : ThemeValidate { public override bool Validate(object obj) { if (obj == null || string.IsNullOrWhiteSpace(obj.ToString())) { return false; } return true; } }
验证数据长度的子类:ThemeAttributeStrLen
public class ThemeAttributeStrLen : ThemeValidate { private int _Min = 0; private int _Max= 0; public ThemeAttributeStrLen(int min, int max) { this._Min = min; this._Max = max; } public override bool Validate(object obj) { if (obj == null || string.IsNullOrWhiteSpace(obj.ToString()) || obj.ToString().Length > _Max || obj.ToString().Length < _Min) { return false; } return true; } }
目前我就定义了以上两个验证子类,今后需要扩展的就自行添加,只要限制继承自ThemeValidate就可以。
我们的验证特性已经定义好了,就是上面的两个子类(ThemeAttributeStrLen和ThemeRequireAttribute),接下来就要把这两个特性标记到实体类的字段属性中去。
在目前的代码中,对company和user实体都做了特性标记,user定义如下:
public partial class UserModel:BaseModel { [StringLength(50), ThemeColumn("Name")] [ThemeRequireAttribute] [ThemeAttributeStrLen(10, 50)] public string Names { get; set; } [Required] [StringLength(100)] public string Account { get; set; } [Required] [StringLength(100)] public string Password { get; set; } [StringLength(200)] public string Email { get; set; } [StringLength(30)] public string Mobile { get; set; } public int? CompanyId { get; set; } [StringLength(500)] public string CompanyName { get; set; } public int State { get; set; } public int UserType { get; set; } public DateTime? LastLoginTime { get; set; } public DateTime CreateTime { get; set; } public int CreatorId { get; set; } public int? LastModifierId { get; set; } public DateTime? LastModifyTime { get; set; } }
如上代码所示,如果一个属性有多个特性的话,如图所示定义:,该定义就表示Names字段包含四个特性StringLength、ThemeColumn、ThemeRequireAttribute、ThemeAttributeStrLen。
Company特性标记如下所示
public partial class Company:BaseModel { [StringLength(500)] [ThemeRequireAttribute] [ThemeAttributeStrLen(10,50)] public string Name { get; set; } [ThemeRequireAttribute] public DateTime CreateTime { get; set; } [ThemeRequireAttribute] public int CreatorId { get; set; } [ThemeRequireAttribute] public int? LastModifierId { get; set; } [ThemeRequireAttribute] public DateTime? LastModifyTime { get; set; } }