zoukankan      html  css  js  c++  java
  • 使用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
       //关闭连接
      }

  • 相关阅读:
    c#向某网址Post信息,并得到Cookies
    调度自动化系统及调度数据网安全分析探讨
    C#winform中怎么将程序最小化到系统托盘
    电力配网自动化解决方案
    .NET (c#) 模拟 Cookie
    调整数组顺序使奇数位于偶数前面
    在字符串中删除特定的字符
    在O(1)时间内删除链表结点
    单链表逆置
    从尾到头输出链表
  • 原文地址:https://www.cnblogs.com/wangchuang/p/2490098.html
Copyright © 2011-2022 走看看