监理公司管理系统 | 工程企业管理系统 | OA系统 | ERP系统 | 造价咨询管理系统 | 工程设计管理系统 | 甲方项目管理系统 | 签约案例 | 客户案例 | 在线试用
X 关闭
常见问题汇总

当前位置:工程项目OA系统 > ERP系统 > 使用说明 > 常见问题汇总

erp软件开发常见问题

申请免费试用、咨询电话:400-8352-114

   经常回顾同事写的开发代码,发现一些问题,总结分析,用于员工培训,或系统优化方面的内容教学。

  文中有问题的的代码我用黑体字标识。

  1 界面与逻辑代码混淆

  这是目前发现的比较严重的问题。框架花费了很大的力气,运用数据绑定,就是为了让界面(控件操作)与后台逻辑(验证与传值)执行相对严格的分离。这里我只能说相对严格的分离,因为后台中一些操作不可避免的需要在前台提示用户确认,或是提示用户输入一些变量值,这部分逻辑也可能会参与在前台界面中。我举例如下。

  private void grid_AfterCellUpdate(object sender, CellEventArgs e)

  {

  if (this.gridUom.ActiveCell == null || !this.gridUom.ActiveCell.IsDataCell)

  return;

  ItemEntity Ientity = itemBindingSource.Current as ItemEntity;

  ItemAuxiLiaryEntity itemAuxiLiaryEntity = gridUom.GetRowListObject(gridUom.ActiveRow) as ItemAuxiLiaryEntity;

  if (gridUom.ActiveRow != null)

  {

  if (BaseCommon.StringCompare(e.Cell.Column.Key, "AuxiLiaryDefault") == 0)

  {

  List indices = entity.ItemAuxiLiaries.FindMatches(ItemAuxiLiaryFields.AuxiLiaryDefault == true & ItemAuxiLiaryFields.Uom != itemAuxiLiaryEntity.Uom);

  if (indices.Count > 0)

  {

  ItemAuxiLiaryEntity customerEntity = entity.ItemAuxiLiaries[indices[0]] as ItemAuxiLiaryEntity;

  customerEntity.AuxiLiaryDefault = false;

  }

  }

  }

  这段代码有以下几个问题

  1 AfterCellUpdate事件完全可以放到后台业务逻辑类中,因为这里只是做业务操作操作,并不涉及到用户确认或输入数据或用户通知的行为,可以归纳的说,除了这三种特殊类型的操作之外(用户确认,输入数据,用户通知)的数据变更,都可以放置到后台业务实体中完成。

  2 性能:这里经过了多次数据转化调用(as操作符),它的性能不太好。而且列名的判断太迟,每次对Grid的单元格的操作都会触发两次数据转化(as操作符)行为。

  这类XX_Changed,XX_Updated,尽量将代码迁移到后台逻辑中。一是为了维护,二是改善性能。

  2 事件的不恰当运用

  Closing事件是正在关闭时发生,还没有关闭,这时可以取消,阻止事件冒泡。Closed是关闭完成,可以做一些其它的资源释放操作。理解这两个事件的区别,有助于合理应用事件。参考下面的代码

  private void chbSuspended_CheckedChanged(object sender, EventArgs e)

  {

  if (chbSuspended.Checked)

  {

  if (!string.IsNullOrEmpty(txtItemNo.Text))

  {

  IPurchaseOrderManager PurchaseOrderManager = ClientProxyFactory.CreateProxyInstance();

  if (PurchaseOrderManager.IsPurchaseOrderExist(bucket))

  {

  DialogResult Result = BaseCommon.ShowConfirm("Item is already in used", null, MessageBoxButtons.OKCancel);

  if (Result != DialogResult.OK)

  {

  chbSuspended.Checked = false;

  }

  }

  从代码的意图中我们可以看出,这是一个需要用户确认的操作。当用户勾选单选框之后,读取数据判断是否合理,提示用户之后将单选框取消选择。在这里,我们完全可以把操作放到Validating事件或是Changing事件中,表达这个值改变之前还需要我们的验证确认,这样对系统的性能开销比较小。如果如上代码所示,等到值改变完成,控件刷新完成之后,再把它还原到未改变之前的状态,这样的性能不好。

  3 应该考虑用空间换时间的性能改善方案

  简单的说,就是把值提前计算好并保存起来,在用的时候直接读取值以取代频繁的计算。高,我做几处说明。

  1)主表与从表的关系数据。主表需要保存从表的数据统计。比如销售订单表头有一个Amount金额字段用于保存明细行的金额累总,这就是一个典型的空间换时间的方案。因为读取表头的字段发生的频率太高了,所以我们不会每次都读取明细行并累总显示。

  2)基础数据表与业务表的数据。比如,我要统计某一个商品的采购订单数量累总,销售订单数量累总,生产任务单数量累总。我们常用的方法是,要用到这些累总时,直接去读取单据数据。而我这里推荐的是空间换时间的方案。做单据业务时,将业务单据的数据提前保存到基础数据表中。再具体来说,就是qty_on_order(商品销售订单数量),qty_on_jo(商品生产订单数量)等累总字段增加到物料表中,在做业务单据时更新物料表相应字段的值。

  3)业务数据表的分析表。比如我们销售送货单,会创建两张表(Shipment/ShipmentDetail)记录此数据。为此,我们还需要提供大量的查询以满足各种业务场景。这时就可以考虑将创建新的数据表来存储相关的查询结果,比如未送货/未完成订单,需要综合订单表或送货表来多纬度的查询,按客户,按销售员,按项目等。这个项目中,会产生比较多的Balance,Journal,Summary等数据表。

  4 合理利用缓存可改善系统效率

  对于一些不常改变的数据项,在实施阶段就固定下来的基础数据,我们可以考虑在系统登入前缓存到系统数据字典中,这样在读取数据时可显示改善效率。一些常有的基础数据,比如单位,货币,销售员,会计帐户,考虑将它们加入到系统缓存中。如用户更改这些数据项,需要更新缓存中的数据项。

  缺少了这项考虑,系统就会出现频繁的从各个基础数据表中读取数据,给系统的效率带来负担。

  5 缺少对数据库NULL值的处理

  对于数量单价类的字段值,它是直接从用户界面中获取,而对于平均单价,最后一次进仓单价,它们的值由系统计算得出。这就会造成前者与后者数据的产生时机不一致,两者为空值NULL的情况会比较多。于是下面的查询过滤条件常常是没有作用的。

  IRelationPredicateBucket bucket=...

  bucket.PredicateExpression.Add(SalesOrderDetailFields.Qty > SalesOrderDetailFields.DeliveryQty);

  对于字符串的字段,null和string.Empty是不同的,在数据库中,NULL和空字符串也是不同的。字符的全角半角也应该控制好。

  6 启动窗体时载入数据项过多

  尽量使用延迟加载数据的模式,而避免启动界面时及时加载所有的数据项。这条规则比较明显的地方是界面中有过多的DropDownList或ComboBox。如果确定要使用这类控件,应该将它的数据项载入时间延迟到控件展开时完成(数据绑定优于逐个数据项增加)。

发布:2021-05-10 14:01    编辑:泛普软件 · hujian    [打印此页]    [关闭]
使用说明
联系方式

成都公司:成都市成华区建设南路160号1层9号

重庆公司:重庆市江北区红旗河沟华创商务大厦18楼

咨询:400-8352-114

加微信,免费获取试用系统

QQ在线咨询