你的位置:首页 > ASP.net教程

[ASP.net教程]WPF根据Oracle数据库的表,生成CS文件小工具


开发小工具的原因:

1、我们公司的开发是客户端用C#,服务端用Java,前后台在通讯交互的时候,会用到Oracle数据库的字段,因为服务器端有公司总经理开发的一个根据Oracle数据库的表生成的class文件,每次都是等服务端都写好了实体类以后,我们再复制、粘贴,修改字段的类型为string,因为在生成的时候,是根据Oracle数据库里的字段类型生成的java文件,但是我们在前后台通信的时候,为了不失精度的一些问题,一般都用string类型来传递,因此每次修改都比较费事。

2、VS2015在封装字段的时候,不会像2012一样,在字段的下方,而是统一的封装到一起,即字段都在上方,属性统一的在下方。

小工具界面效果:

这个是刚打开小工具的页面,连接按钮上面的几个Textbox就是连接数据库时需要的参数。

连接成功以后,把上面的连接部分隐藏掉,为了能有一个稍微大一点的空间,左侧用的是TreeView,父节点是表的Owner,子节点是表

点击左侧TreeView的父节点,则其拥有的表全部显示在右侧

点击左侧的子节点,则显示出来,这个表具体有哪些字段,要生成的VO里的字段就是指这些字段。

NameSpace是指要生成的文件的命名空间,如果不输入,则默认Test,点击生成VO,则会同时生成两个文件,在不同的文件夹下,一个带通知机制,一个不带通知机制,需要哪个是根据实际情况来定。

开发过程:

1、要连接数据库,则自然要有连接数据库的实体类

public class ConnVo : ObjectNotifyPropertyChanged  {    private string connIP;//ip地址    private string connPort;//端口    private string connSid;//服务器名称    private string connUser;//用户名    private string connPwd;//密码    public string ConnIP    {      get      {        return connIP;      }      set      {        connIP = value;        RaisePropertyChanged("ConnIP");      }    }    public string ConnPort    {      get      {        return connPort;      }      set      {        connPort = value;        RaisePropertyChanged("ConnPort");      }    }    public string ConnSid    {      get      {        return connSid;      }      set      {        connSid = value;        RaisePropertyChanged("ConnSid");      }    }    public string ConnUser    {      get      {        return connUser;      }      set      {        connUser = value;        RaisePropertyChanged("ConnUser");      }    }    public string ConnPwd    {      get      {        return connPwd;      }      set      {        connPwd = value;        RaisePropertyChanged("ConnPwd");      }    }  }

ConnVo

2、因为是对Oracle进行操作,因此数据库连接、Select语句神马的肯定少不了,因此专门有一个数据库操作类

public class DBHelper  {    /// <summary>    /// 声明连接    /// </summary>    protected static OracleConnection Connection;    /// <summary>    /// 返回Connection    /// </summary>    /// <param name="ip">地址</param>    /// <param name="port">端口</param>    /// <param name="sid">服务名称</param>    /// <param name="user">用户</param>    /// <param name="pwd">密码</param>    /// <returns>OleDbConnection</returns>    private static OracleConnection ConnForOracle(string ip, string port, string sid, string user, string pwd)    {      string connStr;      connStr = "Data Source=(DESCRIPTION = (ADDRESS_LIST= (ADDRESS = (PROTOCOL = TCP)(HOST = " + ip + ")(PORT = " + port + "))) (CONNECT_DATA = (SERVICE_NAME = " + sid + ")));User ID=" + user + ";Password=" + pwd + ";";      Connection = new OracleConnection(connStr);      return Connection;    }    /// <summary>    /// 连接数据库    /// </summary>    /// <param name="ip">地址</param>    /// <param name="port">端口</param>    /// <param name="sid">服务名称</param>    /// <param name="user">用户</param>    /// <param name="pwd">密码</param>    public static bool OpenConnection(string ip, string port, string sid, string user, string pwd)    {      ConnForOracle(ip, port, sid, user, pwd);      try      {        //不为空 并且 是关闭或者断了的情况下,才连接        if (Connection != null && (Connection.State == System.Data.ConnectionState.Closed || Connection.State == System.Data.ConnectionState.Broken))        {          Connection.Open();          ReturnOwner = Select("SELECT OWNER, TABLE_NAME FROM ALL_TAB_COMMENTS ORDER BY OWNER, TABLE_NAME");        }        MessageBox.Show(Connection.State.ToString());        return true;      }      catch (Exception ex)      {        MessageBox.Show(ex.Message.ToString());        return false;      }    }    /// <summary>    /// 关闭    /// </summary>    public static void CloseConnection()    {      //不为空 并且 是打开状态下才关闭      if (Connection != null && Connection.State == System.Data.ConnectionState.Open)      {        Connection.Close();      }    }    /// <summary>    /// 查询    /// </summary>    /// <param name="sql">SQL语句</param>    /// <returns></returns>    private static DataTable Select(string sql)    {      OracleCommand cmd = new OracleCommand(sql, Connection);      OracleDataAdapter oda = new OracleDataAdapter(cmd);      DataTable dt = new DataTable();      oda.Fill(dt);      cmd.Dispose();      return dt;    }    /// <summary>    /// 获取表名    /// </summary>    /// <param name="owner">拥有者</param>    public static void GetTableName(string owner)    {      ReturnTableName = Select("SELECT OWNER, TABLE_NAME, TABLE_TYPE, COMMENTS FROM ALL_TAB_COMMENTS WHERE OWNER='" + owner + "' ORDER BY OWNER, TABLE_TYPE, TABLE_NAME");    }    /// <summary>    /// 获取表内容    /// </summary>    /// <param name="owner">拥有者</param>    /// <param name="name">表名</param>    public static void GetTableContent(string owner, string name)    {      ReturnTableContent = Select("SELECT COLUMN_NAME, DATA_TYPE, NULLABLE, DATA_LENGTH,(SELECT COMMENTS FROM ALL_COL_COMMENTS WHERE TABLE_NAME = '" + name + "' AND OWNER = '" + owner + "' AND COLUMN_NAME = a.COLUMN_NAME)COMMENTS FROM ALL_TAB_COLUMNS a WHERE TABLE_NAME = '" + name + "' AND OWNER = '" + owner + "' ORDER BY NULLABLE, COLUMN_NAME ");    }    #region 字段    /// <summary>    /// 要返回拥有者    /// </summary>    private static DataTable returnOwner;    public static DataTable ReturnOwner    {      get      {        return returnOwner;      }      set      {        returnOwner = value;      }    }    /// <summary>    /// 返回表名    /// </summary>    private static DataTable returnTableName;    public static DataTable ReturnTableName    {      get      {        return returnTableName;      }      set      {        returnTableName = value;      }    }    /// <summary>    /// 返回表内容    /// </summary>    private static DataTable returnTableContent;    public static DataTable ReturnTableContent    {      get      {        return returnTableContent;      }      set      {        returnTableContent = value;      }    }    #endregion  }

DBHelper

3、为了方便显示,要写一个Oracle的实体类,就是DataGrid显示的内容

public class TableVo : ObjectNotifyPropertyChanged  {    private string schema;//图表    private string name;//名称    private string comments;//注解    private string type;//类型    private string nullable;//是否可空    private string dataLength;//字段长度    public string Schema    {      get      {        return schema;      }      set      {        schema = value;        RaisePropertyChanged("Schema");      }    }    public string Name    {      get      {        return name;      }      set      {        name = value;        RaisePropertyChanged("Name");      }    }    public string Comments    {      get      {        return comments;      }      set      {        comments = value;        RaisePropertyChanged("Comments");      }    }    public string Type    {      get      {        return type;      }      set      {        type = value;        RaisePropertyChanged("Type");      }    }    public string Nullable    {      get      {        return nullable;      }      set      {        nullable = value;        RaisePropertyChanged("Nullable");      }    }    public string DataLength    {      get      {        return dataLength;      }      set      {        dataLength = value;        RaisePropertyChanged("DataLength");      }    }  }

TableVo

4、由于小工具的左侧是一个TreeView,因此有一个TreeView实体,更便于管理和修改,而且此实体中一定要有父节点和子节点,已方便区分,和后期开发

public class PropertyNodeItem:ObjectNotifyPropertyChanged  {    private string icon;    private string parentName;    private string childrenName;    private bool isExpanded;    private List<PropertyNodeItem> children;        public string Icon    {      get      {        return icon;      }      set      {        icon = value;        RaisePropertyChanged("Icon");      }    }    public string ParentName    {      get      {        return parentName;      }      set      {        parentName = value;        RaisePropertyChanged("ParentName");      }    }    public string ChildrenName    {      get      {        return childrenName;      }      set      {        childrenName = value;        RaisePropertyChanged("ChildrenName");      }    }    public bool IsExpanded    {      get      {        return isExpanded;      }      set      {        isExpanded = value;        RaisePropertyChanged("IsExpanded");      }    }    public List<PropertyNodeItem> Children    {      get      {        return children;      }      set      {        children = value;        RaisePropertyChanged("Children");      }    }    public PropertyNodeItem()    {      Children = new List<PropertyNodeItem>();    }  }

PropertyNodeItem

5、创建CS文件,需要同时创建两个,一个带有通知机制,一个不带有通知机制,创建方法无外乎就是拼接String,然后写入文件,很简单,就是在写的过程中,注意一下格式和转义字符

public class CreateVo  {    //不含通知机制    private static string pathVo1 = @"Dis/VoWithoutNotify";    //包含通知机制    private static string pathVo2 = @"Dis/VoWithNotify";    /// <summary>    /// 判断是否存在文件夹,不存在则创建    /// </summary>    /// <returns></returns>    public static bool CreateDirectory()    {      if (!Directory.Exists(pathVo1))      {        Directory.CreateDirectory(pathVo1);      }      if (!Directory.Exists(pathVo2))      {        Directory.CreateDirectory(pathVo2);      }      if (Directory.Exists(pathVo1) && Directory.Exists(pathVo2))        return true;      else        return false;    }    /// <summary>    /// 生成不含通知机制的VO    /// </summary>    /// <param name="NameSpace">命名空间</param>    /// <param name="name">文件名</param>    /// <param name="listName">列表</param>    public static void CreateVoNoINotifyPropertyChanged(string NameSpace,string name,List<TableVo> listName)    {      FileStream fs = new FileStream(pathVo1 + "/" + name + ".cs", FileMode.Create);      StreamWriter sw = new StreamWriter(fs);      sw.Write(CreateCSNoINotifyPropertyChanged(NameSpace,name,listName));      sw.Flush();      sw.Close();      fs.Close();    }    /// <summary>    /// 生成包含通知机制的VO    /// </summary>    /// <param name="NameSpace">命名空间</param>    /// <param name="name">文件名</param>    /// <param name="listName">列表</param>    public static void CreateVoWithINotifyPropertyChanged(string NameSpace, string name, List<TableVo> listName)    {      FileStream fs = new FileStream(pathVo2 + "/" + name + ".cs", FileMode.Create);      StreamWriter sw = new StreamWriter(fs);      sw.Write(CreateCSWithINotifyPropertyChanged(NameSpace, name, listName));      sw.Flush();      sw.Close();      fs.Close();    }    /// <summary>    /// 创建不含通知机制的CS文件    /// </summary>    /// <param name="NameSpace">命名空间</param>    /// <param name="name">文件名</param>    /// <param name="listName">列表</param>    /// <returns></returns>    private static string CreateCSNoINotifyPropertyChanged(string NameSpace,string name,List<TableVo> listName)    {      string content = "";      content += "using System;\r\n";      content += "using System.Collections.Generic;\r\n";      content += "using System.Linq;\r\n";      content += "using System.Text;\r\n";      content += "\r\n";      content += "namespace " + "" + NameSpace + "" + "\r\n";      content += "{\r\n";      content += "  public class " + "" + name + "" + "\r\n";      content += "  {\r\n";      foreach(TableVo s in listName)      {        content += "    private string " + s.Name.ToLower() + ";" + "\r\n";        content += "    /// <summary>\r\n";        content += "    /// " + s.Comments + "\r\n";        content += "    /// </summary>\r\n";        content += "    public string " + s.Name.Substring(0, 1) + s.Name.Substring(1, s.Name.Length-1).ToLower() + "\r\n";        content += "    {\r\n";        content += "      get\r\n";        content += "      {\r\n";        content += "        return " + s.Name.ToLower() + ";\r\n";        content += "      }\r\n";        content += "\r\n";        content += "      set\r\n";        content += "      {\r\n";        content += "        " + s.Name.ToLower() + " = value;\r\n";        content += "      }\r\n";        content += "    }\r\n";        content += "\r\n";      }      content += "  }\r\n";      content += "}\r\n";      return content;    }    /// <summary>    /// 创建包含通知机制的CS文件    /// </summary>    /// <param name="NameSpace">命名空间</param>    /// <param name="name">文件名</param>    /// <param name="listName">列表</param>    /// <returns></returns>    private static string CreateCSWithINotifyPropertyChanged(string NameSpace, string name, List<TableVo> listName)    {      string content = "";      content += "using System;\r\n";      content += "using System.Collections.Generic;\r\n";      content += "using System.Linq;\r\n";      content += "using System.Text;\r\n";      content += "using System.ComponentModel;\r\n";      content += "\r\n";      content += "namespace " + "" + NameSpace + "" + "\r\n";      content += "{\r\n";      content += "  public class " + "" + name + "" + ":INotifyPropertyChanged" + "\r\n";      content += "  {\r\n";      content += "    public event PropertyChangedEventHandler PropertyChanged;\r\n";      content += "    public void RaisePropertyChanged(string propertyName)\r\n";      content += "    {\r\n";      content += "      if (PropertyChanged != null)\r\n";      content += "      {\r\n";      content += "        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));\r\n";      content += "      }\r\n";      content += "    }\r\n";      content += "\r\n";      foreach (TableVo s in listName)      {        content += "    private string " + s.Name.ToLower() + ";" + "\r\n";        content += "    /// <summary>\r\n";        content += "    /// " + s.Comments + "\r\n";        content += "    /// </summary>\r\n";        content += "    public string " + s.Name.Substring(0, 1) + s.Name.Substring(1, s.Name.Length - 1).ToLower() + "\r\n";        content += "    {\r\n";        content += "      get\r\n";        content += "      {\r\n";        content += "        return " + s.Name.ToLower() + ";\r\n";        content += "      }\r\n";        content += "\r\n";        content += "      set\r\n";        content += "      {\r\n";        content += "        " + s.Name.ToLower() + " = value;\r\n";        content += "        RaisePropertyChanged(\"" + s.Name.Substring(0, 1) + s.Name.Substring(1, s.Name.Length - 1).ToLower() + "\");\r\n";        content += "      }\r\n";        content += "    }\r\n";        content += "\r\n";      }      content += "  }\r\n";      content += "}\r\n";      return content;    }  }

CreateVo

6、最后就是需要VM和XAML两个文件来将这些类文件组合到一起,写具体的逻辑关系了

     给TreeView写一个SelectedItemChanged事件,来保证每次选中TreeView时能够获取到当前的选中项,刚开始想写TreeView的SelectedItem属性的,可是怎么也写不出来,后来发现因为这个属性是只读的,所以只能写SelectedItemChanged事件了。

<Border Style="{StaticResource BorderStyle}" BorderThickness="2" Background="{StaticResource BlueThemePageBackground}">    <Grid>      <Grid.RowDefinitions>        <RowDefinition Height="40"/>        <RowDefinition Height="*"/>      </Grid.RowDefinitions>      <Grid Grid.Row="0" Background="LightGray">        <TextBlock Text="Creator for Oracle database" FontSize="25" FontWeight="Black" Style="{StaticResource TextBlockStyle}" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"/>      </Grid>      <Grid Grid.Row="1" Margin="5">        <Grid.RowDefinitions>          <RowDefinition Height="Auto"/>          <RowDefinition Height="Auto"/>          <RowDefinition Height="*"/>          <RowDefinition Height="Auto"/>        </Grid.RowDefinitions>        <Grid Grid.Row="0" DataContext="{Binding ConnectionVo}" Visibility="{Binding DataContext.IsVisibility,RelativeSource={RelativeSource AncestorType=Window,Mode=FindAncestor}}">          <Grid.RowDefinitions>            <RowDefinition Height="*"/>            <RowDefinition Height="*"/>          </Grid.RowDefinitions>          <Grid.ColumnDefinitions>            <ColumnDefinition Width="*"/>            <ColumnDefinition Width="*"/>            <ColumnDefinition Width="*"/>            <ColumnDefinition Width="*"/>            <ColumnDefinition Width="*"/>          </Grid.ColumnDefinitions>          <Border Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Grid.ColumnSpan="5" Style="{StaticResource BorderStyle}"/>          <Line Grid.Row="0" Grid.ColumnSpan="5" Style="{StaticResource HorLineStyle}"/>          <Line Grid.Column="0" Grid.RowSpan="2" Style="{StaticResource VerLineStyle}"/>          <Line Grid.Column="1" Grid.RowSpan="2" Style="{StaticResource VerLineStyle}"/>          <Line Grid.Column="2" Grid.RowSpan="2" Style="{StaticResource VerLineStyle}"/>          <Line Grid.Column="3" Grid.RowSpan="2" Style="{StaticResource VerLineStyle}"/>          <Line Grid.Column="4" Grid.RowSpan="2" Style="{StaticResource VerLineStyle}"/>          <TextBlock Text="IP" Grid.Row="0" Grid.Column="0" Style="{StaticResource TextBlockStyle}"/>          <TextBox Text="{Binding ConnIP}" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Stretch" Style="{StaticResource TextBoxStyle}"/>          <TextBlock Text="Port" Grid.Row="0" Grid.Column="1" Style="{StaticResource TextBlockStyle}"/>          <TextBox Text="{Binding ConnPort}" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Stretch" Style="{StaticResource TextBoxStyle}"/>          <TextBlock Text="SID" Grid.Row="0" Grid.Column="2" Style="{StaticResource TextBlockStyle}"/>          <TextBox Text="{Binding ConnSid}" Grid.Row="1" Grid.Column="2" HorizontalAlignment="Stretch" Style="{StaticResource TextBoxStyle}"/>          <TextBlock Text="User" Grid.Row="0" Grid.Column="3" Style="{StaticResource TextBlockStyle}"/>          <TextBox Text="{Binding ConnUser}" Grid.Row="1" Grid.Column="3" HorizontalAlignment="Stretch" Style="{StaticResource TextBoxStyle}"/>          <TextBlock Text="PassWord" Grid.Row="0" Grid.Column="4" Style="{StaticResource TextBlockStyle}"/>          <TextBox Text="{Binding ConnPwd}" Grid.Row="1" Grid.Column="4" HorizontalAlignment="Stretch" Style="{StaticResource TextBoxStyle}"/>        </Grid>        <Button Content="连接" Command="{Binding LinkCommand}" Grid.Row="1" Visibility="{Binding IsVisibility}" Style="{StaticResource ButtonStyleForSumbit}"/>        <Grid Grid.Row="2">          <Grid.ColumnDefinitions>            <ColumnDefinition Width="300"/>            <ColumnDefinition Width="*"/>          </Grid.ColumnDefinitions>          <TreeView x:Name="tv" ItemsSource="{Binding TreeList}" BorderBrush="{StaticResource BlueThemeBordBursh}" ScrollViewer.HorizontalScrollBarVisibility="Disabled">            <TreeView.ItemContainerStyle>              <Style TargetType="{x:Type TreeViewItem}">                <Setter Property="IsExpanded" Value="{Binding IsExpanded}"/>              </Style>            </TreeView.ItemContainerStyle>            <TreeView.ItemTemplate>              <HierarchicalDataTemplate ItemsSource="{Binding Children}">                <StackPanel Orientation="Horizontal">                  <Image VerticalAlignment="Center" Source="{Binding Icon}" Width="18" Height="18" Margin="0,2"/>                  <TextBlock x:Name="tb" VerticalAlignment="Center" Text="{Binding ChildrenName}" Style="{StaticResource TextBlockStyle}"/>                </StackPanel>              </HierarchicalDataTemplate>            </TreeView.ItemTemplate>            <i:Interaction.Triggers>              <i:EventTrigger EventName="SelectedItemChanged">                <Custom:EventToCommand Command="{Binding SelectChangedCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=TreeView},Path=SelectedItem}"/>              </i:EventTrigger>            </i:Interaction.Triggers>          </TreeView>          <DataGrid Grid.Column="1" ItemsSource="{Binding TableNameGridList}" SelectedItem="{Binding SelectTableName}" Visibility="{Binding VisibilityName}" HorizontalAlignment="Stretch" CanUserAddRows="False" AutoGenerateColumns="False" Style="{StaticResource GreenThemeDataGridStyle}">            <DataGrid.CellStyle>              <Style TargetType="DataGridCell">                <Setter Property="ToolTipService.ToolTip" Value="{Binding RelativeSource={RelativeSource Mode=Self},Path=Content.Text}"/>              </Style>            </DataGrid.CellStyle>            <DataGrid.Columns>              <DataGridTextColumn Header="Schema" Width="*" Binding="{Binding Schema,Mode=OneWay}"/>              <DataGridTextColumn Header="Type" Width="*" Binding="{Binding Type,Mode=OneWay}"/>              <DataGridTextColumn Header="Table Name" Width="*" Binding="{Binding Name,Mode=OneWay}"/>              <DataGridTextColumn Header="Comments" Width="*" Binding="{Binding Comments,Mode=OneWay}"/>            </DataGrid.Columns>          </DataGrid>          <DataGrid Grid.Column="1" ItemsSource="{Binding TableContentGridList}" Visibility="{Binding VisibilityContent}" HorizontalAlignment="Stretch" CanUserAddRows="False" AutoGenerateColumns="False" Style="{StaticResource GreenThemeDataGridStyle}">            <DataGrid.CellStyle>              <Style TargetType="DataGridCell">                <Setter Property="ToolTipService.ToolTip" Value="{Binding RelativeSource={RelativeSource Mode=Self},Path=Content.Text}"/>              </Style>            </DataGrid.CellStyle>            <DataGrid.Columns>              <DataGridTextColumn Header="Column Name" Width="*" Binding="{Binding Name,Mode=OneWay}"/>              <DataGridTextColumn Header="Column Comments" Width="*" Binding="{Binding Comments,Mode=OneWay}"/>              <DataGridTextColumn Header="Type" Width="*" Binding="{Binding Type,Mode=OneWay}"/>              <DataGridTextColumn Header="Nullable" Width="*" Binding="{Binding Nullable,Mode=OneWay}"/>              <DataGridTextColumn Header="DataLength" Width="*" Binding="{Binding DataLength,Mode=OneWay}"/>            </DataGrid.Columns>          </DataGrid>        </Grid>        <StackPanel Grid.Row="3" HorizontalAlignment="Center" Orientation="Horizontal">          <TextBlock Text="NameSpace" FontStyle="Italic" FontWeight="Bold" Foreground="Red" Style="{StaticResource TextBlockStyle}"/>          <TextBox Width="150" Text="{Binding Ns}" Style="{StaticResource TextBoxStyle}" Margin="5,0,100,0"/>          <Button Content="创建VO" Command="{Binding CreateVoCommand}" CommandParameter="{Binding ElementName=tv,Path=SelectedItem}" Style="{StaticResource ButtonStyleForSumbit}" Margin="0,0,30,0"/>          <Button Content="关闭" Command="{Binding CloseCommand}" Style="{StaticResource ButtonStyleForCancel}"/>        </StackPanel>      </Grid>    </Grid>  </Border>

XAML
public class MainWindowVM : ViewModelBase  {    public MainWindowVM()    {      SetConnVo();    }    #region 字段    /// <summary>    /// 命名空间    /// </summary>    private string ns = "";    public string Ns    {      get      {        return ns;      }      set      {        ns = value;        RaisePropertyChanged("Ns");      }    }    /// <summary>    /// 连接类    /// </summary>    private ConnVo connectionVo = new ConnVo();    public ConnVo ConnectionVo    {      get      {        return connectionVo;      }      set      {        connectionVo = value;        RaisePropertyChanged("ConnectionVo");      }    }    /// <summary>    /// 表    /// </summary>    private TableVo table;    public TableVo Table    {      get      {        return table;      }      set      {        table = value;        RaisePropertyChanged("Table");      }    }    /// <summary>    /// 左侧列表    /// </summary>    private ObservableCollection<PropertyNodeItem> treeList = new ObservableCollection<PropertyNodeItem>();    public ObservableCollection<PropertyNodeItem> TreeList    {      get      {        return treeList;      }      set      {        treeList = value;        RaisePropertyChanged("TreeList");      }    }    /// <summary>    /// 原始列表    /// </summary>    private List<PropertyNodeItem> orgList = new List<PropertyNodeItem>();    public List<PropertyNodeItem> OrgList    {      get      {        return orgList;      }      set      {        orgList = value;        RaisePropertyChanged("OrgList");      }    }    /// <summary>    /// 父列表    /// </summary>    private List<string> ownerList = new List<string>();    public List<string> OwnerList    {      get      {        return ownerList;      }      set      {        ownerList = value;        RaisePropertyChanged("OwnerList");      }    }    /// <summary>    /// 连接成功以后,就隐藏上边的部分    /// </summary>    private Visibility isVisibility = Visibility.Visible;    public Visibility IsVisibility    {      get      {        return isVisibility;      }      set      {        isVisibility = value;        RaisePropertyChanged("IsVisibility");      }    }    /// <summary>    /// 表名选中项    /// </summary>    private TableVo selectTableName = new TableVo();    public TableVo SelectTableName    {      get      {        return selectTableName;      }      set      {        selectTableName = value;        RaisePropertyChanged("SelectTableName");      }    }    /// <summary>    /// 表名list    /// </summary>    private ObservableCollection<TableVo> tableNameGridList = new ObservableCollection<TableVo>();    public ObservableCollection<TableVo> TableNameGridList    {      get      {        return tableNameGridList;      }      set      {        tableNameGridList = value;        RaisePropertyChanged("TableNameGridList");      }    }    /// <summary>    /// 表内容    /// </summary>    private ObservableCollection<TableVo> tableContentGridList = new ObservableCollection<TableVo>();    public ObservableCollection<TableVo> TableContentGridList    {      get      {        return tableContentGridList;      }      set      {        tableContentGridList = value;        RaisePropertyChanged("TableContentGridList");      }    }    /// <summary>    /// 表名是否显示    /// </summary>    private Visibility visibilityName = Visibility.Collapsed;    public Visibility VisibilityName    {      get      {        return visibilityName;      }      set      {        visibilityName = value;        RaisePropertyChanged("VisibilityName");      }    }    /// <summary>    /// 表内容是否显示    /// </summary>    private Visibility visibilityContent = Visibility.Collapsed;    public Visibility VisibilityContent    {      get      {        return visibilityContent;      }      set      {        visibilityContent = value;        RaisePropertyChanged("VisibilityContent");      }    }    #endregion    #region 函数    /// <summary>    /// 给连接的东西赋值    /// </summary>    private void SetConnVo()    {      ConnectionVo.ConnIP = "*****";      ConnectionVo.ConnPort = "1521";      ConnectionVo.ConnSid = "*****";      ConnectionVo.ConnUser = "swzg";      ConnectionVo.ConnPwd = "*****";    }    /// <summary>    /// DataTable转换到List    /// </summary>    /// <param name="dt"></param>    /// <returns></returns>    private void DataTableToList(DataTable dt)    {      //获取最原始的List      var orgList = (from dataTable in dt.AsEnumerable()              select new PropertyNodeItem()              {                ParentName = dataTable["OWNER"].ToString(),                ChildrenName = dataTable["TABLE_NAME"].ToString()              }).ToList();      OrgList.AddRange(orgList);      DataTable newdt = new DataView(dt.Columns["OWNER"].Table).ToTable(true, "OWNER");//去除重复,只留下OWNER      //只获得Owner列表      var newList = (from dataTable in newdt.AsEnumerable()              select dataTable["OWNER"].ToString());      OwnerList.AddRange(newList);    }    /// <summary>    /// 给Treeview赋值    /// </summary>    /// <param name="listOrg">原始列表</param>    /// <param name="listNew">Own列表</param>    private void SetTree(List<PropertyNodeItem> listOrg, List<string> listNew)    {      TreeList.Clear();      for (int i = 0; i < listNew.Count; i++)      {        PropertyNodeItem node = new PropertyNodeItem()        {          ParentName = listNew[i].ToString(),          ChildrenName = listNew[i].ToString(),          Icon = @"../Icon/father.ico",          IsExpanded = false        };        ForeachPropertyNode(node, listOrg, listNew[i].ToString());        TreeList.Add(node);      }    }    /// <summary>    /// 向父节点中添加子节点    /// </summary>    /// <param name="node">节点</param>    /// <param name="listOrg">原始的列表</param>    /// <param name="parentName">父节点名称</param>    private void ForeachPropertyNode(PropertyNodeItem node, List<PropertyNodeItem> listOrg, string parentName)    {      var listChildren = (from dataTable in listOrg.AsEnumerable()                where dataTable.ParentName == parentName                select new PropertyNodeItem()                {                  ParentName = dataTable.ParentName.ToString(),                  ChildrenName = dataTable.ChildrenName.ToString(),                  Icon = @"../Icon/children.ico",                  IsExpanded = false                });      node.Children.AddRange(listChildren);    }    /// <summary>    /// 获取表名列    /// </summary>    /// <param name="owner"></param>    private void GetTableNameList(string owner)    {      TableNameGridList.Clear();      DBHelper.GetTableName(owner);      var list = (from dt in DBHelper.ReturnTableName.AsEnumerable()            select new TableVo()            {              Schema = dt["OWNER"].ToString(),              Name = dt["TABLE_NAME"].ToString(),              Type = dt["TABLE_TYPE"].ToString(),              Comments = dt["COMMENTS"].ToString()            }).ToList();      for (int i = 0; i < list.Count; i++)      {        TableVo tablevo = new TableVo()        {          Schema = list[i].Schema,          Comments = list[i].Comments,          Name = list[i].Name,          Type = list[i].Type        };        TableNameGridList.Add(tablevo);      }    }    /// <summary>    /// 获取表内容    /// </summary>    /// <param name="owner"></param>    /// <param name="name"></param>    private void GetTableContentList(string owner, string name)    {      TableContentGridList.Clear();      DBHelper.GetTableContent(owner, name);      var list = (from dt in DBHelper.ReturnTableContent.AsEnumerable()            select new TableVo()            {              Name = dt["COLUMN_NAME"].ToString(),              Type = dt["DATA_TYPE"].ToString(),              Comments = dt["COMMENTS"].ToString(),              Nullable = dt["NULLABLE"].ToString(),              DataLength = dt["DATA_LENGTH"].ToString()            }).ToList();      for (int i = 0; i < list.Count; i++)      {        TableVo tablevo = new TableVo()        {          Name = list[i].Name,          Type = list[i].Type,          Comments = list[i].Comments,          Nullable = list[i].Nullable,          DataLength = list[i].DataLength        };        TableContentGridList.Add(tablevo);      }    }    /// <summary>    /// 获得数据库里的字段名    /// </summary>    /// <returns></returns>    private List<string> GetListName()    {      List<string> list = new List<string>();      if (TableContentGridList.Count > 0)      {        for (int i = 0; i < TableContentGridList.Count; i++)        {          list.Add(TableContentGridList[i].Name.ToLower());        }        return list;      }      return null;    }    #endregion    #region 按钮    /// <summary>    /// 连接按钮    /// </summary>    private RelayCommand linkCommand;    public RelayCommand LinkCommand    {      get      {        return linkCommand = new RelayCommand(() =>         {           if (DBHelper.OpenConnection(ConnectionVo.ConnIP, ConnectionVo.ConnPort, ConnectionVo.ConnSid, ConnectionVo.ConnUser, ConnectionVo.ConnPwd))           {             DataTableToList(DBHelper.ReturnOwner);             SetTree(OrgList, OwnerList);             IsVisibility = Visibility.Collapsed;           }           else           {             MessageBox.Show("连接失败!");           }         });      }    }    /// <summary>    /// 关闭按钮    /// </summary>    private RelayCommand closeCommand;    public RelayCommand CloseCommand    {      get      {        return closeCommand = new RelayCommand(() =>         {           DBHelper.CloseConnection();           Messenger.Default.Send<string>(null, "WinClose");         });      }    }    /// <summary>    /// 创建VO按钮    /// </summary>    private RelayCommand<PropertyNodeItem> createVoCommand;    public RelayCommand<PropertyNodeItem> CreateVoCommand    {      get      {        return createVoCommand = new RelayCommand<PropertyNodeItem>(p =>         {           if (p == null || (p.ParentName.Equals(p.ChildrenName) && string.IsNullOrEmpty(SelectTableName.Name)))             return;           if (p.ParentName.Equals(p.ChildrenName) && !string.IsNullOrEmpty(SelectTableName.Name))           {             GetTableContentList(p.ParentName, SelectTableName.Name);             //创建文件夹             CreateVo.CreateDirectory();             CreateVo.CreateVoNoINotifyPropertyChanged(Ns != "" ? Ns : "test", SelectTableName.Name, TableContentGridList.ToList());             CreateVo.CreateVoWithINotifyPropertyChanged(Ns != "" ? Ns : "test", SelectTableName.Name, TableContentGridList.ToList());           }           else           {             //创建文件夹             CreateVo.CreateDirectory();             CreateVo.CreateVoNoINotifyPropertyChanged(Ns != "" ? Ns : "test", p.ChildrenName, TableContentGridList.ToList());             CreateVo.CreateVoWithINotifyPropertyChanged(Ns != "" ? Ns : "test", p.ChildrenName, TableContentGridList.ToList());           }         });      }    }    #endregion    #region 事件    /// <summary>    /// Treeview切换事件    /// </summary>    private RelayCommand<PropertyNodeItem> selectChangedCommand;    public RelayCommand<PropertyNodeItem> SelectChangedCommand    {      get      {        return selectChangedCommand = new RelayCommand<PropertyNodeItem>(p =>        {          if (p.ParentName.Equals(p.ChildrenName))          {            GetTableNameList(p.ParentName);            VisibilityName = Visibility.Visible;            VisibilityContent = Visibility.Collapsed;          }          if (!p.ParentName.Equals(p.ChildrenName))          {            GetTableContentList(p.ParentName, p.ChildrenName);            VisibilityName = Visibility.Collapsed;            VisibilityContent = Visibility.Visible;          }        });      }    }    #endregion  }

ViewModel

注意事项:

在最开始的连接Oracle中,我用的是OleDbConnection,连接语句里用到了“Provider=OraOLEDB.Oracle.1;”,也就是用到了Oracle的驱动,这个在没有注册的时候会弹出

未在本地计算机注册“OraOLEDB.Oracle.1”,在我的机器上注册成功,好使了,但是在我同事的机器上,注册成功了,依然会有这个提示,不能成功连接数据库,因此,最终,选用了Oracle.ManagedDataAccess.DLL文件,它是oracle官方的托管驱动,有6M多,但是有了这个文件以后,直接使用OracleConnection就不会爆出连接问题了。

总结:做这个小工具没有什么难度,用到的方法有Linq、Oracle的Select语句、StreamWriter写入文件等,但是对于我们的开发还是蛮实用的,希望看到的朋友可以根据你们的项目需求,做出其他版本的小工具,大家一起探讨、成长。