简单的来说,winForm开发下的经验可以几乎不用改动的移植到Mobile开发下来,当然Mobile开发也有她自己的许多丰富的内容及自己的缺陷,这些方面会在以后的文章中提到。
下面把做的第一个Mobile开发小项目的代码贴出来,共享之。
项目功能描述:
1. 做一个Web Service,提供查询远程服务端数据以及将本地修改后的数据提交给远程服务端的功能;
2. Mobile程序调用该Web Service,将远程数据缓存到本地,在本地进行修改,然后一次性提交过去;
要求:不要使用任何Compact Framework提供的RDA或Replication数据同步功能。
实施步骤1:提供所需的Web Service
假定我们的远程数据保存在SQL Server 2005的一个数据库中。
在以下代码中,我定义的Web method既有返回DataSet对象的,也有交错字符串数组的。这两者都可以被很好的序列化和反序列化。
该Web Service使用ASP.NET编写。
以DataTable的形式返回雇员信息表
[WebMethod(Description = "以DataTable的形式返回雇员信息表")]
public DataTable GetEmployeesTable(string connStr)
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
DataTable dataTable = new DataTable();
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string sql = "SELECT * FROM Employee";
SqlCommand command = new SqlCommand(sql);
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
using (SqlConnection conn = new SqlConnection(connStr))
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
conn.Open();
command.Connection = conn;
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
SqlDataAdapter dataAdapter = new SqlDataAdapter(command);
dataAdapter.Fill(dataTable);
}
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return dataTable;
}
以DataSet的形式返回雇员信息表
[WebMethod(Description = "以DataSet的形式返回雇员信息表")]
public DataSet GetEmployeesSet(string connStr)
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
DataSet dataset = new DataSet();
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string sql = "SELECT * FROM Employee";
SqlCommand command = new SqlCommand(sql);
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
using (SqlConnection conn = new SqlConnection(connStr))
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
conn.Open();
command.Connection = conn;
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
SqlDataAdapter dataAdapter = new SqlDataAdapter(command);
dataAdapter.Fill(dataset);
}
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return dataset;
}
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
以string[][]的形式返回雇员信息表
[WebMethod(Description = "以string[][]的形式返回雇员信息表")]
public string[][] GetEmployeesArrays(string connStr)
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
string[][] empsArray;
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
DataTable dataTable = GetEmployeesTable(connStr);
int numRows = dataTable.Rows.Count;
empsArray = new string[numRows][];
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for (int i = 0; i < numRows; i++)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
DataRow row = dataTable.Rows[i];
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
empsArray[i] = new string[]
{ row["Id"].ToString(),
row["Name"].ToString(),
row["Address"].ToString()};
}
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return empsArray;
}
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
将更改后的记录表格提交到雇员信息表中
[WebMethod(Description = "将更改后的记录表格提交到雇员信息表中")]
public void UpdateEmployeesTable(string connStr, DataSet changedDataSet)
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
string sql = "UPDATE Employee SET Name=@name, Address=@addr WHERE Id=@id";
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
SqlParameter paraId = new SqlParameter("@id", null);
SqlParameter paraName = new SqlParameter("@name", null);
SqlParameter paraAddr = new SqlParameter("@addr", null);
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
SqlCommand command = new SqlCommand(sql);
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
command.Parameters.AddRange(new SqlParameter[]
{ paraId, paraName, paraAddr });
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
using (SqlConnection conn = new SqlConnection(connStr))
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
conn.Open();
command.Connection = conn;
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
foreach (DataRow row in changedDataSet.Tables[0].Rows)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
paraId.Value = row["Id"];
paraName.Value = row["Name"];
paraAddr.Value = row["Address"];
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
command.ExecuteNonQuery();
}
}
}
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
将更改后的记录数组提交到雇员信息表中
[WebMethod(Description = "将更改后的记录数组提交到雇员信息表中")]
public void UpdateEmployeesArray(string connStr, string[][] changedRecords)
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
string sql = "UPDATE Employee SET Name=@name, Address=@addr WHERE Id=@id";
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
SqlParameter paraId = new SqlParameter("@id", null);
SqlParameter paraName = new SqlParameter("@name", null);
SqlParameter paraAddr = new SqlParameter("@addr", null);
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
SqlCommand command = new SqlCommand(sql);
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
command.Parameters.AddRange(new SqlParameter[]
{ paraId, paraName, paraAddr });
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
using (SqlConnection conn = new SqlConnection(connStr))
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
conn.Open();
command.Connection = conn;
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
for (int i = 0; i < changedRecords.Length; i++)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
string[] empRecord = changedRecords[i];
paraId.Value = empRecord[0];
paraName.Value = empRecord[1];
paraAddr.Value = empRecord[2];
![InBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
command.ExecuteNonQuery();
}
}
}
![None.gif](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
鉴于为了减少通过Web Service传递的数据量,我们提供了两种返回值的Web Method,相应的有2种提交更改的方式。
注意在使用数组传递数据时,我为什么不用二维数组,而选择交错数组呢?而且这里的交错数组没一个数组的维数都是相同的。主要是由于如果使用二维数组,在获取维数上很麻烦,如
string[,] empsArr = new string[2, 3],我在使用传递过来的empsArr对象时,如果不额外的传递一个维数参数,我根本就没法知道这个东西是几行的(几列是可以知道的,因为这个是因需要固定的,而行数却是变化的。);采用交错数组可以很方便的获取维数:
string[][] empsArr = new string[][3];
int length = empsArr.Length;
我