关于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/

原文地址:https://www.cnblogs.com/EmptyFS/p/3240315.html