快乐生活 轻松工作

利用XML反序列化读取数据库记录

假设我们需要从数据库中读取一条记录并把它在UI上显示出来,你会怎么做?
比如说我们想从SQL2000中pub数据库中找到最贵的书。通常我们会这样:
SqlConnection conn = new SqlConnection("server=localhost;database=pubs;integrated security=SSPI");
conn.Open();
SqlCommand cmd = new SqlCommand("select top 1 title_id,title,price from titles order by price desc", conn);
SqlDataReader reader = cmd.ExecuteReader();
id = reader.GetString["title_id"];
name = reader.GetString["title_name"];
price = reader.GetDouble["price"];
......
这样不仅类似的代码充斥在系统的各个角落里,而且,当数据库改动的时候开发人员异常痛苦。但是如果我们利用XML反序列化我们就可以轻松地化腐朽为神奇。我们先定义一个类以存储数据(为了简单起见,我们直接用成员变量,在现实中建议用属性):
   public class Book
   {
       [XmlAttribute("title_id")]
       public string Id;

       [XmlAttribute("title")]
       public string Name;

       [XmlAttribute("price")]
       public double Price;
   };
然后读取数据库记录并依赖.NET的XML反序列化自动产生Book的实例:
SqlConnection conn = new SqlConnection("server=localhost;database=pubs;integrated security=SSPI");
conn.Open();
SqlCommand cmd = new SqlCommand("select top 1 title_id,title,price from titles Book order by price desc for xml auto", conn);
XmlReader reader = cmd.ExecuteXmlReader();
XmlSerializer serializer = new XmlSerializer(typeof(Book));
Book book = serializer.Deserialize(reader) as Book;
这样我们就可以直接使用book中的数据了。当数据库中的字段类型,名称被改变时,或者需要返回的字段个数有增减时,我们只要修改Book就可以搞定一切!

那么如果我们的查询返回多条记录的话,比如返回所有的书籍,我们是否可以使用XML反序列呢?答案是肯定的。我们可以通过定义一个容器来解决这个问题。
   public class Books
   {
       [XmlArrayAttribute("List")]
       public Book[] memList;

       [System.Xml.Serialization.XmlIgnore]
       public int Count
       {
           get{return memList==null ? 0 : memList.Length;}
       }
   }
但是这里我们会遇到一个麻烦,就是XML格式的问题。SQL的FOR XML AUTO仅能返回单个数据的XML元素列表,像这样。
<Book .... />
<Book .... />
而XML反序列要求XML为下列格式:
<Books>
   <List>
       <Book .... />
       <Book .... />
   </List>
</Books>
把Books中的"List"修改为"Book"并不能解决问题。通过SQL中的for exl explict也许可以解决问题但你一定会为脑细胞的过度死亡而伤心。解决办法是我们自己给它加个头"<Books><List>"以及一个尾"</List></Book>"。怎么加?答案是定义个TextReader,暂且叫他DataTextReader吧,然后让XmlReader使用我们的DataTextReader。在DataTextReader里我们根据情况在数据库返回的XML里插入我们需要的Tag。由于代码较长,我把它放到了其他地方,按这里这里察看。

现在我们可以这样得到多行记录了:
DataTextReader reader = new DataTextReader("Books|List",memConnStr,memQueryStr);
XmlTextReader tempReader = new XmlTextReader(reader);
Books b = memBooksSerializer.Deserialize(tempReader) as Books;
tempReader.Close();
reader.Close();
通过访问b.memList并提供下标,你可以访问任何一条记录了。Books中的Count是用来说明如何定义与数据无关的附加属性。


转载自http://dev365.yculblog.com/archive.2005,7,1.html

posted on 2006-02-21 21:53  思考 学习 总结  阅读(768)  评论(0)    收藏  举报