2011-03-13 29 views
0

我有一個數據表,它給了我的列名,列的數據類型和最大字符長度。 returntype應該是一個列表,我怎樣才能在一個列表中鏈接列名和數據類型。請幫忙。如何從一個列表中的數據表中返回數據類型?

try 
     { 
      List<string> tablelist = new List<string>(); 
      DataTable dt; 
      conn.Open(); 
      SqlCommand cmd = new SqlCommand("SELECT column_name,data_type,character_maximum_length FROM "+ dbPropertiesobj.DBName +".information_schema.columns WHERE table_name = '"+ TableName+"' ", conn); 
      SqlDataAdapter sqlda = new SqlDataAdapter(cmd); 
      dt = new DataTable(); 
      sqlda.Fill(dt); 
      for (int i = 0; i < dt.Rows.Count; i++) 
      { 
       string dtrow = dt.Rows[i].ItemArray[0].ToString(); //gets only the columnname 
       tablelist.Add(dtrow); 
      } 
      return tablelist; // need the datatype and maximum character length along with the name. 
     } 
     catch (Exception ex) 
     { 
      return null; 
     } 

回答

1

你有很多東西與此代碼回事。我完全重寫了它,這不是最簡單的代碼,甚至也不是最好的代碼,但它是爲了說明需要了解更多或正在處理的領域。

研究異常處理,尤其是何時使用它以及如何使用它。切勿寫入吞噬錯誤的嘗試塊。如果此方法返回null,你打算做什麼?表名是不好的?連接失敗了嗎?用戶可能會也可能不會修復這個錯誤,但是您會吞噬它。現在沒有人知道它是什麼。

更糟糕的是,甚至可能沒有人知道在這裏發生的錯誤取決於您對null做了什麼。永遠不要吞下這樣的錯誤。應用程序應該在發生錯誤的地方失敗。還要小心返回這樣的空值。當您返回空值,然後執行其他操作時,應用程序可能會在某個地方出現故障,而原始錯誤現在很難找到並修復。編寫框架時,您可能偶爾會以這種風格返回空值。對於普通的應用程序,通常不需要它,幾乎也不是一個好主意。

良好質量的生產代碼通常只包含很少的異常處理,因爲您應該使用條件來處理任何您可以預見的事情。任何你無法預見的東西通常也無法處理。你可能有很多嘗試...... finally塊存在清理資源,但一個應用程序應該包含很少的實際try..catch黑色。通常,您會讓錯誤傳播回調用堆棧,最終處理程序在應用程序關閉之前通知用戶。

以下仍然不是您可以編寫的最佳代碼。我保持原來的合理性,並刪除了一些快捷方式,使其更清晰。研究差異,並從那裏去

public class SomeClass 
{ 

    //Use parameters rather than accessing module level properties 
    private IList<ColumnInformation> GetColumnInformationForTable(string dbName, string tableName) 
    { 
     // Favor object oriented styles and meaningful names. Your method does not return a list of tables 
     // it returns a list of column meta data 
     List<ColumnInformation> columnInformations = new List<ColumnInformation>(); 

     // Avoid SQL conncatenation if at all possible. NEVER concatenate where parameters into SQL commands and NEVER EVER with single quotes. 
     // Here table name requires concatenation but the select parameter TableName does not. 
     string selectCmdString = "SELECT column_name,data_type,character_maximum_length FROM " + dbName + ".information_schema.columns WHERE table_name = @TableName"; 

     // Use parameters. Get everything ready first, don't open connections prematurely and only wrap error prone code in try blocks. 
     SqlCommand cmd = new SqlCommand(selectCmdString, conn); 
     SqlParameter tableNameParameter = new SqlParameter("@TableName", tableName); 
     cmd.Parameters.Add(tableNameParameter); 

     // Use a DataReader since you cannot modify this data anyway. 
     // This also shows an appropriate use of a try block to ensure a connection gets closed, 
     // but better yet, open your reader with the CommandBehavior set to close 
     // and get rid of this try block altogether 
     try 
     { 
      //Reconsider use of a module or global level connection. May be better to create a new here. 
      conn.Open(); 
      SqlDataReader reader = cmd.ExecuteReader(); 
      //Favor OOP styles rather than indexes and arrays and repeated calls to determine things like Rows.Count in a loop 
      while(reader.Read()) 
      { 
       // Favor explicit member access rather than index acess. 
       //YOUR HOMEWORK! Study DataReader access and rewrite the code below to handle possible nulls in length field. Use a method based on evaluating conditionals, DO NOT use a method based on a try block. 
       ColumnInformation columnInformation = new ColumnInformation(reader["column_name"].ToString(), reader["data_type"].ToString(), (int)reader["character_maximum_length"].ToString()); 
       columnInformations.Add(columnInformation); 
      } 
      reader.Close(); 
     } 
     finally 
     { 
      // The only reason to use the try is to make sure the connection gets closed here. A better approach 
      // is to use the CommandBehavior.CloseConnection option and get rid of the try finally block completely. 
      // But NEVER just wrap a bunch of code in try blocks arbitrarily, swallow any errors and return a null. 
      conn.Close(); 
     } 


     return columnInformations; 
    } 


} 

public class ColumnInformation 
{ 
    private string _columnName; 
    private string _dataType; 
    private int _columnLength; 

    public string ColumnName 
    { 
     get { return _columnName; } 
    } 

    public string DataType 
    { 
     get { return _dataType; } 
    } 

    public int ColumnLength 
    { 
     get { return _columnLength; } 
    } 

    public ColumnInformation(string columnName, string dataType, int columnLength) 
    { 
     _columnName = columnName; 
     _dataType = dataType; 
     _columnLength = columnLength; 
    } 
} 
+0

感謝很多...這真的很有幫助。幫助我重新思考我的編碼方法和標準。現在必須重新排列我的代碼。 ThnQ – NewBie 2011-03-13 08:22:23

1

爲什麼不是3元組對象列表(即帶3個值的元組)?不知道申請宣告該名單的確切語法,但每個條目會是這樣的:

Tuple.Create(column_name, datatype, max_length) 
相關問題