silverlight 中 支持datatable写法

来源:互联网 发布:春秋战国士阶层 知乎 编辑:程序博客网 时间:2024/05/01 15:57

我们的WebService接收到的DataSet类型默认会被替换成ArrayOfXElement类型,该类型下有两个节点,

第一个结点为表结构的,包含了表的各个列,示例如下:

  1. <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  2.   <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
  3.     <xs:complexType>
  4.       <xs:choice minOccurs="0" maxOccurs="unbounded">
  5.         <xs:element name="Table">
  6.           <xs:complexType>
  7.             <xs:sequence>
  8.               <xs:element name="第一列列名" type="xs:string" minOccurs="0" />
  9.               .............
  10.             </xs:sequence>
  11.           </xs:complexType>
  12.         </xs:element>
  13.       </xs:choice>
  14.     </xs:complexType>
  15.   </xs:element>
  16. </xs:schema>
复制代码

第二个节点是表内容了

  1. <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
  2.   <NewDataSet xmlns="">
  3.     <Table diffgr:id="Table1" msdata:rowOrder="0">
  4.       <USERID>988</USERID>
  5.       ............
  6.     </Table>
  7.     <Table diffgr:id="Table1" msdata:rowOrder="0">
  8.       <USERID>989</USERID>
  9.       ............
  10.     </Table>
  11.   </NewDataSet>
  12. </diffgr:diffgram>
复制代码

从表中提取数据解析并且放入实体类对象中非常麻烦,因此想出了一个投机取巧的办法。
我发现<Table>标签中的内容,跟实体类对象序列化xml的结果是一样儿一样儿的。
我猜测,我将其提取出来并拼接成一个完整的实体对象序列化后的xml,然后将其反序列化成对象。。。。是可行的!
经实验,确实可行。下面是代码,一个通用类的代码。

  1.     public class Command
  2.     {
  3.         static string head = "<?xml version=\"1.0\"?><{0} xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">";
  4.         static string tail = "</{0}>";
  5.         /// <summary>
  6.         /// 讲ArrayOfXElement类型中的结点内容反序列化为一个实体对象,实体类型可变
  7.         /// </summary>
  8.         /// <typeparam name="T">实体类型</typeparam>
  9.         /// <param name="aoxe">WebService返回的DataSet类型的替代类型</param>
  10.         /// <returns></returns>
  11.         public static T GetEntityForDataSetXml<T>(ArrayOfXElement aoxe)
  12.         {
  13.             T t = default(T);
  14.             try
  15.             {
  16.                 var content = (XElement)((XElement)((XElement)aoxe.Nodes[1].LastNode).FirstNode);//提取第2个结点的内容
  17.                 StringBuilder sb = new StringBuilder();
  18.                 sb.Append(string.Format(head, typeof(T).Name));//添加xml头
  19.                 foreach (var item in content.Nodes())//便利结点
  20.                 {
  21.                     sb.Append(item.ToString());//取出内容
  22.                 }
  23.                 sb.Append(string.Format(tail, typeof(T).Name));//添加结尾
  24.                 string ss = sb.ToString();
  25.                 StringReader sr = new StringReader(ss);//创建流,这是序列化必须的
  26.                 //声明序列化对象实例serializer  
  27.                 XmlSerializer serializer = new XmlSerializer(typeof(T));
  28.                 //反序列化,并将反序列化结果值赋给变量i
  29.                 t = (T)serializer.Deserialize(sr);//反序列化后强制转化为对象
  30.                 sr.Close();
  31.                 sr.Dispose();
  32.                 sb.Clear();
  33.             }
  34.             catch
  35.             {
  36.             }
  37.             return t;
  38.         }
  39.         /// <summary>
  40.         /// 获取多个实体对象
  41.         /// </summary>
  42.         /// <typeparam name="T">实体类型</typeparam>
  43.         /// <param name="aoxe"></param>
  44.         /// <returns></returns>
  45.         public static List<T> GetAllEntitiesForDataSetXml<T>(ArrayOfXElement aoxe)
  46.         {
  47.             List<T> listT = new List<T>();
  48.             XmlSerializer serializer = new XmlSerializer(typeof(T));
  49.             T t = default(T);
  50.             try
  51.             {
  52.                 var content = (XElement)((XElement)((XElement)aoxe.Nodes[1].LastNode));//取出第二个结点中的内容
  53.                 StringBuilder sb = new StringBuilder();
  54.                 foreach (var item in content.Nodes())
  55.                 {
  56.                     sb.Append(string.Format(head, typeof(T).Name));
  57.                     foreach (var obj in ((XElement)item).Nodes())
  58.                     {
  59.                         sb.Append(obj.ToString());
  60.                     }
  61.                     sb.Append(string.Format(tail, typeof(T).Name));
  62.                     string ss = sb.ToString();
  63.                     StringReader sr = new StringReader(ss);
  64.                     //反序列化,并将反序列化结果值赋给变量i
  65.                     t = (T)serializer.Deserialize(sr);
  66.                     listT.Add(t);
  67.                     sr.Close();
  68.                     sr.Dispose();
  69.                     sb.Clear();
  70.                 }
  71.             }
  72.             catch
  73.             {
  74.             }
  75.             return listT;
  76.         }
  77.     }
复制代码

注意事项,对应的表需要对应的实体类型,实体类型中包含表的字段,
且实体类中的需要加上点东西,如下:

  1.     [XmlRoot]
  2.     public class UserInfo
  3.     {
  4.         [XmlElement]
  5.         public string USERID { get; set; }
  6.         ...........
  7.     }
复制代码

这里的UserInfo也就是上面泛型方法中的的T。。。。第一个返回的是类型为T的对象,第二个返回的是List<T>.....

0 0