几种Code Value Web输入的解决方案
https://files.cnblogs.com/neozhu/AutocompletedSetKeyValue.rar
在实际应用系统开发过程中会经常遇到的情况是在做数据库设计的时候为了满足第二范式消除数据冗余和数据的一致性,就会存在类似单位,币值等基础代码的维护,通常情况基础代码库设计是Key Description这样的结构,对于业务实例会保存基础代码的Key,而显示出来的时候会显示描述的信息.
图表 1[对应关系]
场景一
在GridView中显示Product表中的信息,用户需要看到的一定是单位名称,国家的名称,因为他们不会关心也看不懂代码。
实现方式1
通过视图关联查询或直接Sql查询
例如:select productCode,ProductName,c1.CurrName,c2.CountryName,u.UnitName from Product,Curr c1,Country C2,Unit u where …..
分析
这样的做法执行效率很差需要对多个表进行扫描,而且容易出错,所以我们不建议这样去做
实现方式2
先将Product表填充到一个DataTable中,把基础参数表用Hashtable或是Dictionary<T,T>缓存起来,然后通过DataTable中的参数字段进行替换。
分析
一般的做法都是这样实现,好处是不容易出错,效率明显提高很多,所有的mapping都在内存中完成。可以编写通用的方法去实现
实现方式3
采用ORM框架定义Product实体类,通过实体类的属性进行Key,Value的mapping,例如
public string UnitCode
{
get {
return list.Unit[_UnitCode];
}
set {
_UnitCode = value;
foreach (KeyValuePair<string, string> p in list.Unit)
{
if (p.Value == _UnitCode)
_UnitCode= p.Key;
}
//_UnitCode= "";
}
}
分析
和实现方式2的区别是直接在每个对象输出的时候进行替换,而不是在绑定的时候。这样做的好处是双向的进行mapping,在赋值的时候帮你保存code,显示的时候显示name。对于程序开发来说比实现方式2多写代码,但是好处是运用了ORM设计思想对于程序的结构非常好。
场景二
新增一个Product记录,用户会通过输入代码快速检索到对应的名称,然后进行提交。前台提交的是名称,后台保存的是代码。
实现方式1
最简单方式采用DropDownlist绑定基础代码表,KeyField,ValueField分别对应Code,Name
分析
由于DropDownlist不支持键盘操作,没有办法进行检索。好处是开发方便
实现方式2
采用window.showModalDialog()方法弹出窗口选择后回调结果赋值代码如下,后台在最终保存到数据库前可以通过一个hashtable进行Code,Name替换。
主窗体
function getCurrCode() {
var returnVal = window.showModalDialog("CodeList.aspx", null, "dialogHeight:450px;dialogWidth:500px; center:yes;help:no;resizable:no;status:no;")
var CodeText = $get('ctl00_ContentPlaceHolder1_FormView1_CurrCodeHiddenField');
var NameText = $get('ctl00_ContentPlaceHolder1_FormView1_CurrNameTextBox');
if (CodeText != null)
CodeText.value = returnVal.Code;
if (NameText != null)
NameText.value = returnVal.Name;
//document.getElementById("textboxBookName").value = returnVal.book_name;
return false;
}
子窗体
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
StringBuilder cstext = new StringBuilder();
//cstext.Append("<script type=\"text/javascript\"> function DoClick() {");
cstext.Append(string.Format(" getCodeListbyIdx({0}) ", e.Row.RowIndex + 1));
//cstext.Append("}</script>");
e.Row.Attributes.Add("onclick", cstext.ToString()
);
}
function getCodeListbyIdx(rowIdx) {
var company = new Object();
var row = getGridRow(rowIdx);
company.Name = row.cells[2].innerText;
company.Code = row.cells[0].innerText;
//alert(company.CompanyCode + company.CompanyName + company.SvrIp);
window.returnValue = company;
window.close();
return false;
}
分析
这是目前大多数项目的做法,好处是检索很方便,支持多个参数的传递,同样的问题是不支持纯键盘操作,还有就是需要IE解除屏蔽弹出窗口。
实现方式3
采用asp.net ajax controlToolikt自带的autocomplete控件实现,如果要实现key,value同时返回需要编写一点代码
后台代码
[WebMethod]
public string[] GetUnitCodeList(string prefixText, int count)
{
Pub_paraDataContext db = new Pub_paraDataContext();
//Table<UNIT> unittable = db.GetTable<UNIT>();
var resultQuery = from c in db.UNITs
where SqlMethods.Like(c.UNIT_CODE, "%" + prefixText + "%")
select c;
int len = resultQuery.ToArray<UNIT>().Length;
if (len > count)
{
len = count;
}
List<string> items = new List<string>(len);
foreach (UNIT u in resultQuery)
{
items.Add(AjaxControlToolkit.AutoCompleteExtender.CreateAutoCompleteItem(u.UNIT_NAME, u.UNIT_CODE));
}
return items.ToArray();
}
前台js
function UnitCodeSelected(source, eventArgs) {
/*var unitCodeText = $get("ctl00_ContentPlaceHolder1_FormView1_UnitCodeTextBox");*/
var CodeText = $get('ctl00_ContentPlaceHolder1_FormView1_UnitCodeTextHiddenField');
if (CodeText != null)
CodeText.value = eventArgs.get_value();
}
分析
是一种ajax的实现方法,编写少量代码就能实现代码的检索,和纯键盘操作,是值得推荐的做法
总结
推荐使用ORM实体类的方式进行数据操作,尽量采用ajax技术实现页面的互操作。