使用NHibernate完成对数据的批量导入 .

在对数据处理时往往要实现对数据的批量导入功能。一般的处理方法如下

1、读入TXT文件的一行

2、按照顺序放入到指定的对象(这里用到反射功能)

3、根据类中的主键判断是否已经存在在数据库中

4、如果存在,则更新,如果不存在则插入。

 

这里每个要导入的类必须实现IPK接口,返回主键信息。

判断是否存在使用如下方法:

    //多个参数一定要有别名
    String sql = "from "+_type +" as o"+ whereClause;
    //查找
    IList op = Connect.getSession().Find(sql);

其中where字句是根据主键信息生成的字符串。

注意:多个参数一定给类一个别名

 

代码如下

 public void process()
  {
   String sLine;//记录读入的行
   string [] arrSplit;//按照分隔符得到的字符串数组
   IList pkList;//主键对应的Property
   string whereClause;

   //打开指定的文件
   //如果打开文件不成功则返回
   if(!this.openFile()) return;
   //则打开一个新的连接
   ISession sess = Connect.getSession();
   //建立一个Tran
   ITransaction tr = sess.BeginTransaction();


   
   //读入一行
   while ((sLine = sr.ReadLine()) != null && sLine.Trim().Length > 0)
   {
    //根据Type新生成一个对象
    object o = Activator.CreateInstance(_type);
    if(!(o is IPK))
    {
     MessageBox.Show("不能从IPK继承主键返回属性!");
     return ;
    }
    //主键
    pkList = ((IPK)o).Primary;
    //条件字句
    whereClause =" where ";

    object io;//待输入的数据
    //根据分割符,形成字符串数组
    arrSplit = sLine.Split('/t');
    int i=0;//列计数器
    int j=0;//主键计数器
    //插入对应的Class
    //不能使用_type.GetPropeties得到Property,因为显示的顺序不同了。
    //应该使用GetColumns得到显示的顺序,即可得到
    //foreach(PropertyInfo pi in _type.GetProperties())
    foreach(string s in showList)
    {
     //得到指定的PropertyInfo
     PropertyInfo pi = _type.GetProperty(s);
     //MessageBox.Show(pi.PropertyType.ToString());
     if(pi.PropertyType==typeof(DateTime))
     { //处理日期型
      //Assert.AreEqual(typeof(DateTime),DateTime.Parse(arrSplit[i]).GetType(),arrSplit[i]+"  "+i+" "+pi.Name);
      //如果日期为空,则默认为9999-9-9
      if(arrSplit[i]==null ||arrSplit[i]=="")
       io = DateTime.Parse("9999-9-9");
      else
      { //判断是否有日期分割符号
       if(arrSplit[i].Substring(4,1)!="/"||arrSplit[i].Substring(4,1)!="-")
       {
        int year = Convert.ToInt16(arrSplit[i].Substring(0,4));
        int month = Convert.ToInt16(arrSplit[i].Substring(4,2));
        int day = Convert.ToInt16(arrSplit[i].Substring(6,2));
        io = new DateTime(year,month,day);
       }
       else
        //日期不为空,则将字符型转换为日期型
        io = DateTime.Parse(arrSplit[i]);
      }
     }
     else
      //如果不是日期型,则直接使用
      io=arrSplit[i];
     if(pi.PropertyType ==typeof(Char))
      io = Convert.ToChar(io);
     //这里需要根据类型插入
     pi.SetValue(o,io,null);

 

     //如果是主键则,加入条件语句
     
     if(pkList.Contains(pi.Name))
     {
      whereClause+="o."+pi.Name +"="+"'"+io+"'";
      if(j<pkList.Count-1)
       whereClause+=" and ";
      j++;
     }

     //计数器加一
     i++;
    }
   
    
    //如果存在则更新,如果不存在,则插入
    //多个参数一定要有别名
    String sql = "from "+_type +" as o"+ whereClause;
    //查找
    IList op = Connect.getSession().Find(sql);
    //如果找到,表示对象存在在数据库中
    if(op.Count>0)
     //保对对象
     sess.Update(o);
    else
     //插入
     sess.Save(o);

   }
   //完成->提交 Commit
   try
   {
    tr.Commit();  
   }
   catch(HibernateException ex)
   {
    if (tr!=null) tr.Rollback(); 
    throw ex;
   }
   finally
   {
    //关闭连接
    sess.Close();
    //关闭文件
    sr.Close();
   }
   //提交出错,则RollBack
   //关闭连接
  }

posted on 2012-05-08 14:52  HOT SUMMER  阅读(1872)  评论(0编辑  收藏  举报

导航