開發小工具的緣由:java
一、咱們公司的開發是客戶端用C#,服務端用Java,先後臺在通信交互的時候,會用到Oracle數據庫的字段,由於服務器端有公司總經理開發的一個根據Oracle數據庫的表生成的class文件,每次都是等服務端都寫好了實體類之後,咱們再複製、粘貼,修改字段的類型爲string,由於在生成的時候,是根據Oracle數據庫裏的字段類型生成的java文件,可是咱們在先後臺通訊的時候,爲了避免失精度的一些問題,通常都用string類型來傳遞,所以每次修改都比較費事。node
二、VS2015在封裝字段的時候,不會像2012同樣,在字段的下方,而是統一的封裝到一塊兒,即字段都在上方,屬性統一的在下方。git
小工具界面效果:github
這個是剛打開小工具的頁面,鏈接按鈕上面的幾個Textbox就是鏈接數據庫時須要的參數。sql
鏈接成功之後,把上面的鏈接部分隱藏掉,爲了能有一個稍微大一點的空間,左側用的是TreeView,父節點是表的Owner,子節點是表數據庫
點擊左側TreeView的父節點,則其擁有的表所有顯示在右側服務器
點擊左側的子節點,則顯示出來,這個表具體有哪些字段,要生成的VO裏的字段就是指這些字段。oracle
NameSpace是指要生成的文件的命名空間,若是不輸入,則默認Test,點擊生成VO,則會同時生成兩個文件,在不一樣的文件夾下,一個帶通知機制,一個不帶通知機制,須要哪一個是根據實際狀況來定。ide
開發過程:函數
一、要鏈接數據庫,則天然要有鏈接數據庫的實體類
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"); } } }
二、由於是對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 }
三、爲了方便顯示,要寫一個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"); } } }
四、因爲小工具的左側是一個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>(); } }
五、建立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; } }
六、最後就是須要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>
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 }
注意事項:
在最開始的鏈接Oracle中,我用的是OleDbConnection,鏈接語句裏用到了「Provider=OraOLEDB.Oracle.1;」,也就是用到了Oracle的驅動,這個在沒有註冊的時候會彈出
未在本地計算機註冊「OraOLEDB.Oracle.1」,在個人機器上註冊成功,好使了,可是在我同事的機器上,註冊成功了,依然會有這個提示,不能成功鏈接數據庫,所以,最終,選用了Oracle.ManagedDataAccess.DLL文件,它是oracle官方的託管驅動,有6M多,可是有了這個文件之後,直接使用OracleConnection就不會爆出鏈接問題了。
總結:作這個小工具沒有什麼難度,用到的方法有Linq、Oracle的Select語句、StreamWriter寫入文件等,可是對於咱們的開發仍是蠻實用的,但願看到的朋友能夠根據大家的項目需求,作出其餘版本的小工具,你們一塊兒探討、成長。