In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
解析大型.NET ERP系统代码的示例分析,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
1 对用户输入做过多的约定和假设
配置文件App.config中有一个设定报表路径的配置节:
在程序中有一个销售报表文件SalesReport.rpt,用代码调用这个报表,可能会写成:
string salesReport=ReportPath + "SalesReport.rpt";
因为路径末尾没有加反斜线,会抛出找不到报表文件的异常(FileNotFoundException)。
经过修改,可以考虑在配置前的末尾强制要加反斜线\,修改之后的配置节如下:
经过这样的修改,上面代码运行正常。
为此,我认为应该在程序中考虑增加一个判断,对于路径默认没有带反斜线\的,给它加一个。程序代码也就是一行:
if (!reportPath.EndsWith("\\"))
reportPath += "\\";
这个例子也可以通过调用方法System.IO.Path.Combine实现,避免用户没有输入反斜线的问题。
再举一个例子,比如IP地址后如果用户没有加端口号码,程序中做一个简单的判断,加上默认的端口号,不强制约定用户的输入的值,比较下面的两种配置方法。
2 在数据库服务器中可以处理的查询,移动到程序端处理
这一条产生的原因在于C#有很好用的foreach语句,永远不会抛出越界异常。所以就产生了一些偷懒的做法,宁愿把数据读到程序中处理,也不想优化SQL语句查询。参考下面的代码,我遇到后都是直接强制要求重写。
IPrefetchPath3 prefetchPath=new PrefetchPath3((int)EntityType.SalesOrderEntity);
prefetchPath.Add(PartEntity.PrefetchPathSalesOrderDetail);
SalesOrderEntity order=salesOrderManager.GetPart("SC201507",prefetchPath); string description=string.Empty; foreach(SalesOrderDetailEntity orderDetail in order.SalesOrderDetail) { if(orderDetail.ItemNo="FLEX102030009") { description=entity.Description; break;
}
}
能在数据库服务器中做的事情,就不应该移动到代码中处理,这样没有效率,代码没有质量。
3 数据库SQL语句未考虑到重复执行或是自动化部署
坏味道的代码:
ALTER TABLE JobOrder ADD FiscalYear DECIMAL(4,0), PeriodNo DECIMAL(2,0)
应该修改成下面的代码。
IF NOT EXISTS(SELECT C.NAME FROM DBO.SYSCOLUMNS C, DBO.SYSOBJECTS O WHERE O.ID = C.ID AND O.NAME = 'CompanyParameter' AND C.NAME = 'POApprovalRequired')
BEGIN
Alter Table CompanyParameter ADD POApprovalRequired [nvarchar] (1) DEFAULT 'N'
END
4 DataTable 的用法中,用数字作索引,在维护时很难看见数字列名的含义
坏味道的代码:
string cachePath=string.Empty;
DataTable table =queryManager.FetchTableBySqlCommand(query);
foreach (DataRow row in table.Rows)
cachePath = row.ItemArray[2].ToString();
应该修改成用列名作索引:
string cachePath=string.Empty;
DataTable table =queryManager.FetchTableBySqlCommand(query);
foreach (DataRow row in table.Rows)
cachePath = row.ItemArray["CachePath"].ToString();
5 字符串操作没有考虑大小写
字符串判断比较可以用等号(=)操作符,我推荐的写法是用Equal方法,传入参数是否区分大小写。
字符串搜索也需要考虑大小写问题,比如下面的代码,不区大小写搜索。
string findWath="SO2015"; if (txtOrderNo.Text.IndexOf(findWhat, 0, StringComparison.InvariantCultureIgnoreCase) != -1)
字符串空值判断用string.IsNullOrWhiteSpace,字符串设空值用string.Empty。
6 长时间运行任务时,没有设置光标为等待状态,控件的状态也未变灰
执行任务前
UseWaitCursor = true;
btnAdd.Enable=false;
任务执行完成之后
UseWaitCursor = false;
btnAdd.Enable=true;
7 打开文件对话框没有设置合适的标题和文件类型过滤器
这是个小细节的地方,从stackoverflow中搜索几个filter供参考用。
public const string ImageFilter = "Image files (*.jpg, *.jpeg, *.jpe, *.jfif, *.png,*.gif,*.bmp) | *.jpg; *.jpeg; *.jpe; *.jfif; *.png;*.gif;*bmp"; public const string PDFFilter = "PDF files (*.pdf) | *.pdf"; public const string ExcelFilter = "Excel Files|*.xls;*.xlsx;*.xlsm";
8 删除数据时,如非必要,不用先读取到客户端再执行删除。
如有验证逻辑,考虑用过滤条件传递到数据库中验证数据,代替读取数据到程序中执行验证。
9 日期时间没有考虑到小时分钟值
DateTime.Now 是带小时分钟的, DateTime.Today是不带时间的。曾经有一段时间,总是查不到今天做的日记帐数据,总是要求客户把时间查询时间范围提前一天,原因是DateTime.Now带有小时分钟值。
10 SQL脚本文件编码
需要保存的格式是UTF8,避免GB2312或是BIG5导致乱码。
11 同一个数据库中出现多种命名习惯
SalesOrder 首字母大写
Sales_Order 单词用下划线分开
SL_Sales_Order 加模块前缀
12 系统默认值来源没有依据
采购订单税率默认为17点,一年定期银行利息是2.2***BC分析的三个值依次是85,15,5。
这些默认值都应该加一个功能来存储,而不是直接在代码中写死默认值。
13 常量值不统一
主要是日期时间***最小值,推荐下面的代码,用于设定公共变量值。
private static readonly DateTime _dateTimeMinValue = new DateTime(1753, 1, 1, 0, 0, 0, 0);
private static readonly DateTime _dateTimeMaxValue = new DateTime(2099, 12, 31, 0, 0, 0, 0);
public static DateTime DateTimeMinValue
{
get { return _dateTimeMinValue; }
}
public static DateTime DateTimeMaxValue
{
get { return _dateTimeMaxValue; }
}
数据库中时间值为空值字段,可以设置值为NULL,也可以用DateTimeMinValue。
对于特殊类财务报表,必须要有一个时间范围,用DateTimeMinValue。
myEntity.SetNewFieldValue((int)MyEntityFieldIndex.MyDateField, null);
14 没有发挥数据绑定的的威力
WinForms的数据绑定是双向的,可以将实体对象通过数据源控件取到DataGridView控件中。
坏味道的代码:
string customerName=gridQuotation.Rows[0].Cell[0].Value;
应该是:
QuotationEntity quotation= detailBindingSource.Current as QuotationEntity;
QuotationEntity quotation = this.gridQuotation.GetRowListObject(row) as QuotationEntity;
string customerName=quotation.CustomerName
15 数据验证没有借助于.NET的正则表达式。
坏味道:
try
{
Convert.ToDecimal("123abc456"); return true; } catch { return false;
}
应该是
Regex regex = new Regex("a{1,2}"); Match m = regex.Match("123abc456") if(m.Success) { //验证成功
}
这些验证方式可以封装为公共方法,实现代码复用。
16 数据库查询没有考虑NULL值情况
坏味道的代码:
ResultsetFields fields = new ResultsetFields(1);
fields.DefineField(PurchaseRequisitionDetailFields.Qty, 0);
应该是:
DbFunctionCall dbFunQty = new DbFunctionCall("ISNULL", new object[] { PurchaseRequisitionDetailFields.Qty, 0 }); EntityField2 efieldQty = new EntityField2(PurchaseRequisitionDetailFields.Qty.Name, dbFunQty);
itemFields.DefineField(efieldQty, 0);
相当于ISNULL函数调用 ISNULL(Qty,0) 。
看完上述内容,你们掌握解析大型.NET ERP系统代码的示例分析的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.