关于SubSonic3.0插件使用Json反序列化获得的实体进行更新操作时,只能执行添加而不能执行修改(编辑)操作的处理
由于目前开发的项目使用云计算技术,客户端只进行UI与相关事件的功能开发,而所有的计算与处理都放到了服务器端,客户端与数据库没有任何关联,所以服务器端与客户端使用我们自己开发的通讯加密方式进行,而具体的数据内容传输就转成Json方式。客户端对数据进行添加与修改操作时,先将内容存储到实体中,然后转换成Json字串进行压缩加密处理后提交到服务器端,服务器端接收到后进行解压解密处理后,对Json字串进行反序列化处理存储到对应的实体当中,然后再进行相应的操作。
在开发框架时还没有什么问题,而进行具体的功能开发时,发现进行添加是没有问题,但编辑时还是执行添加操作,并没有执行编辑操作。经过半天的DeBug跟踪,才发现原来SubSonic3.0只有查询出来的实体才能更新,比如使用构造函数查询的实体new Operator(x => x.Id == 10), 或者是DataModel.Operator.SingleOrDefault(x => x.Id < 10)等,而使用Json反序列化转实体进行更新时,并没有触发IsNew()和IsLoaded()这两个更新标识,所以在执行更新操作时(如var model = (DataModel.Operator)JsonConvert.DeserializeObject("", typeof(DataModel.Operator));),this._dirtyColumns.Count的值一直为0(这里存储的是将要进行更新的字段),插件检查上面标识后就默认为添加操作了。具体修改如下:
打开ActiveRecord.tt模版,找到构造函数 public <#=tbl.ClassName#>() ,将它修改成下面内容:
public <#=tbl.ClassName#>(){ //使用Json直接转换实体时,由于未激活更新功能,会导致只能添加不能更新,所以必须设置下面值, //设置后Json转换的实体和实体中不包含的字段(字段类型为字符串的字段,数值型的不会提交),全部都会提交到数据库中 //比如某些值在后台操作时并不需要提交的(如登陆IP),在实体中没有进行赋值,这时就会默认为""将数据库中的其他值给覆盖了 SetIsLoaded(true); _db=new <#=Namespace#>.<#=DatabaseName#>DB(); Init(); }
模版构造函数修改后图例:
模版修改后生成的代码图例:
修改后重新生成插件就可以进行编辑操作了,不过这样改了后,会产生新的问题,由于开启了全部更新功能,会将一些不该更新的字段也给更新覆盖了,所以还须做下面的相关修改:
在模版中找到public void Update(IDataProvider provider)函数,将它修改成下面内容:
public void Update(IDataProvider provider){ <#if(tbl.Columns.Any(x=>x.Name=="ModifiedBy")){#> if(String.IsNullOrEmpty(this.ModifiedBy)) this.ModifiedBy=Environment.UserName; <#}#> <#if(tbl.Columns.Any(x=>x.Name=="ModifiedOn")){#> this.ModifiedOn=<#=DatabaseName#>DB.DateTimeNowTruncatedDownToSecond(); <#}#> if(this._dirtyColumns.Count>0){ //如果存在过滤字段 if (_columns.Count > 0) { //定义装载过滤字段的IColumn容器 IList<IColumn> list = new List<IColumn>(); //遍历过滤字段容器 for (int i = 0; i < _columns.Count; i++) { //遍历将要进行更新操作的列 for (int j = 0; j < this._dirtyColumns.Count; j++) { //如果该列名存在过滤表中,即不需要进行更新操作 if (_columns[i] == this.Columns[j].Name) { //将它装载进IColumn容器中,待后面进行操作 list.Add(this.Columns[j]); } } } //判断IColumn容器是否装载了内容 if (list.Count > 0) { //遍历容器 for (int i = 0; i < list.Count; i++) { //将需要过滤的字段从更新列中移除 this._dirtyColumns.Remove(list[i]); } } } _repo.Update(this,provider); _dirtyColumns.Clear(); } OnSaved(); } /// <summary>定义不进行更新操作的字段的容器</summary> private List<string> _columns = new List<string>(); /// <summary> /// 添加将要过滤的字段 /// </summary> /// <param name="columnName">字段名称</param> public void AddFilterColumns(string columnName) { _columns.Add(columnName); }
模版构造函数修改后图例:
模版修改后生成的代码图例:
修改后将插件重新生成就可以调用了,请看下面的调用例子:
本文章为原创内容,转载请保留下面信息。
发表本编内容,只要主为了和大家共同学习共同进步,有兴趣的朋友可以加加Q群:SubSonic3.0学习群(327360708)或Email给我(1654937#qq.com),大家一起探讨,由于本人工作很繁忙,如果疑问请先留言,回复不及时也请谅解。
想了解更多SubSonic3.0的相关问题,请观注博客:http://www.cnblogs.com/EmptyFS/