本文目的

本文旨在提供通过读取xml文件快速更新数据表的方法,为本人在项目应用中的实践所的,所涉及到的内容都比较基础,还请各位博友拍砖。

序幕

Linq to sql给我们的orm影射带来了极大的便利,实体类写很少的代码就可以完成数据库表的增删查改,也使我们能够更加专注于业务逻辑;而Xml的应用也是相当广泛,如今的SOA很大程度上是利用了Xml格式的SOAP消息来进行交互。有的时候我们会碰到需要读取xml保存到数据库的情况,在没有Linq的时候,可能我们会通过XmlSerializer的Deserialize方法来反序列化Xml生成相对应的net class,然后操作net class插入数据库,如果不采用orm的话,代码量和利用XmlDocument直接操作Xml更新数据库没有什么差别,那么现在有了Linq to sql,反序列化的net class和Linq to sql的Entity可以优雅的结合到一起,看看减轻了我们多少的工作量?

XmlSerializer.Deserialize 

首先我们看一下XmlSerializer.Deserialize的例子
使用的xml文件
norm.xml

读取xml通过deserialize和linq to sql快速更新数据表<Norm>
读取xml通过deserialize和linq to sql快速更新数据表  
<TradeName>纺织</TradeName>
读取xml通过deserialize和linq to sql快速更新数据表  
<SubmittedDate>2008-04-28</SubmittedDate>
读取xml通过deserialize和linq to sql快速更新数据表  
<Index>
读取xml通过deserialize和linq to sql快速更新数据表    
<IndexName>信息化投入比</IndexName>
读取xml通过deserialize和linq to sql快速更新数据表    
<IndexNum>500</IndexNum>
读取xml通过deserialize和linq to sql快速更新数据表  
</Index>
读取xml通过deserialize和linq to sql快速更新数据表  
<Index>
读取xml通过deserialize和linq to sql快速更新数据表    
<IndexName>环保改善率</IndexName>
读取xml通过deserialize和linq to sql快速更新数据表    
<IndexNum>300</IndexNum>
读取xml通过deserialize和linq to sql快速更新数据表  
</Index>
读取xml通过deserialize和linq to sql快速更新数据表
</Norm>

对应的net class
norm.cs

读取xml通过deserialize和linq to sql快速更新数据表public class Norm
    }

注意Index[] Indexs的Attribute设置为XmlElement("Index"),CLR可以帮助我们将多个Index Element反序列化为Indexs数组。
 Program.cs

读取xml通过deserialize和linq to sql快速更新数据表class Program
    }

读取xml通过deserialize和linq to sql快速更新数据表

反序列化结合Linq to sql使用

首先给出表结构

读取xml通过deserialize和linq to sql快速更新数据表CREATE TABLE [dbo].[Norm] (
读取xml通过deserialize和linq to sql快速更新数据表    
[NormID] [int] IDENTITY (11NOT NULL ,
读取xml通过deserialize和linq to sql快速更新数据表    
[TradeName] [nvarchar] (30NOT NULL ,
读取xml通过deserialize和linq to sql快速更新数据表    
[SubmittedDate] [datetime] NOT NULL 
读取xml通过deserialize和linq to sql快速更新数据表
ON [PRIMARY]
读取xml通过deserialize和linq to sql快速更新数据表
CREATE TABLE [dbo].[Index] (
读取xml通过deserialize和linq to sql快速更新数据表    
[IndexID] [int] IDENTITY (11NOT NULL ,
读取xml通过deserialize和linq to sql快速更新数据表    
[IndexName] [nvarchar] (30NOT NULL ,
读取xml通过deserialize和linq to sql快速更新数据表    
[IndexNum] [float] NOT NULL ,
读取xml通过deserialize和linq to sql快速更新数据表    
[NormID] [int] NOT NULL 
读取xml通过deserialize和linq to sql快速更新数据表
ON [PRIMARY]
读取xml通过deserialize和linq to sql快速更新数据表
读取xml通过deserialize和linq to sql快速更新数据表
ALTER TABLE [dbo].[Index] ADD 
读取xml通过deserialize和linq to sql快速更新数据表    
CONSTRAINT [FK_Index_Norm] FOREIGN KEY 
读取xml通过deserialize和linq to sql快速更新数据表    (
读取xml通过deserialize和linq to sql快速更新数据表        
[NormID]
读取xml通过deserialize和linq to sql快速更新数据表    ) 
REFERENCES [dbo].[Norm] (
读取xml通过deserialize和linq to sql快速更新数据表        
[NormID]
读取xml通过deserialize和linq to sql快速更新数据表    )


norm和index为1对多的关系,norm的主键为normid(int not null identity),index的主键为indexid(int not null identity),normid为index表的外键

下面给出解决方案,最简单的方法就是修改linq to sql的设计器生成的代码
读取xml通过deserialize和linq to sql快速更新数据表

只需要在相应的Property上加上XmlElementAttribute就可以,由于代码太长,这里我只列出自己建立的linq to sql实体和DataContext

读取xml通过deserialize和linq to sql快速更新数据表public class NormDataContext : DataContext

注意norm和index的构造函数的内容一定要有,否则会报NSERT 语句与 COLUMN FOREIGN KEY 约束冲突,另外把相应的需要反序列化的Property标记XmlElement,不需要的如NormID,IndexID标记XmlIgnore(这个对应数据表的自增长列,利用linq to sql的DataContext完成剩下的提交工作),看代码

读取xml通过deserialize和linq to sql快速更新数据表                Norm norm = serializer.Deserialize(new XmlNodeReader(xn)) as Norm;         
读取xml通过deserialize和linq to sql快速更新数据表                NormDataContext ndc 
= new NormDataContext("server=server;database=BlackJack;uid=sa;pwd=");
读取xml通过deserialize和linq to sql快速更新数据表                StreamWriter sw 
= new StreamWriter(AppDomain.CurrentDomain.BaseDirectory+"/log1.txt"true); // Append
读取xml通过deserialize和linq to sql快速更新数据表
                ndc.Log = sw;
读取xml通过deserialize和linq to sql快速更新数据表                ndc.Norms.InsertOnSubmit(norm);
读取xml通过deserialize和linq to sql快速更新数据表                ndc.SubmitChanges();
读取xml通过deserialize和linq to sql快速更新数据表                sw.Close();
读取xml通过deserialize和linq to sql快速更新数据表


后记

在完成这段代码前,我一直在网上找类似的解决方案,但比较少,也可能是我孤陋寡闻,是不是linq系列将来会考虑支持这种方式感觉微软在xml序列化/反序列化做的很好,提供了很多的Attribute,使我们不用编写代码就能够完成工作,这里我也是抛砖引玉,还望园子里的朋友不吝赐教,另外我也把我的问题提出来,我在反序列化net class中利用XmlRootAttribute加入了自己的namespace,可是总是无法正确的反序列化,不知道怎么回事?

源代码

1 修改linq设计器生成的代码的例子

2 自己写的例子

相关文章:

  • 2021-11-16
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-01-04
  • 2021-08-30
猜你喜欢
  • 2021-06-13
  • 2018-09-29
  • 2021-05-23
  • 2021-10-08
  • 2021-06-05
相关资源
相似解决方案