2013-02-15 43 views
0

可以說我有兩個看起來像這樣的類。用於從SQL Server讀取數據的通用函數

class Foo1 
{ 
    public String P1 { get; set; } 
    public String P2 { get; set; } 
} 

class Foo2 
{ 
    public String P3 { get; set; } 
    public String P4 { get; set; } 
} 

P1,P2,P3和P4是沒有絲毫關係。與Foo1Foo2相同。它們代表完全不同的對象。

我有兩個數據庫表,其中有一列Foo1和Foo2對象。我必須創建一個List<Foo1>List<Foo2>

返回Foo1和Foo2的存儲過程的輸入是不同的。

這裏是我的問題 - 我想創建一個能夠連接到數據庫並獲取或者Foo1或foo2的清單,我想

起初,我想過這樣的事情

internal static SqlDataReader GetData(String Proc,NameValueCollection InputParams,SqlConnection conn, ref String Err) 
{ 

    using (SqlCommand cmd = conn.CreateCommand()) 
    { 
     try 
     { 
      cmd.CommandType = CommandType.StoredProcedure; 
      cmd.CommandText = Proc; 
      conn.Open(); 

      SqlCommandBuilder.DeriveParameters(cmd); 


      foreach (SqlParameter p in cmd.Parameters) 
      { 
       if (p.Direction == ParameterDirection.Input) 
       { 

        if (InputParams[p.ParameterName.ToLower().Substring(1)] != String.Empty) 
        { 
         p.Value = InputParams[p.ParameterName.ToLower().Substring(1)]; 
         p.DbType = DbType.AnsiString; 
        } 
        else 
        { 
         Err += "<argumentnotfound>" + p.ParameterName + "</argumentnotfound>";          
        } 
       } 
       else p.Value = DBNull.Value; 

      } 
      return cmd.ExecuteReader(); 
     } 
     catch (Exception e) 
     { 
      return null; 
     }  
    } 
} 

我一個泛型函數不喜歡在此函數外部返回SqlDataReader或創建和關閉SqlConnection的想法。

理想情況下,我想通過這個函數裏面的「閱讀器」對象進行迭代,但在回報List<Foo1>List<Foo2>。我可以想到的一種解決方案是這樣的

 internal static List<Object> GetData(NameValueCollection InputParams, ref String Err, String ClassName, String Proc) 
{ 
    List<Object> [] objectlist = new List<Object>(); 
    using (SqlConnection conn = getConnection()) 
    { 
     using (SqlCommand cmd = conn.CreateCommand()) 
     { 
      try 
      { 
       /* 
        ~~ Same as before 
       */ 
       SqlDataReader reader = cmd.ExecuteReader(); 
       while(reader.Read()) 
       { 

        if(ClassName == "Foo1") 
        { 
         Foo1 f = new Foo1(); 
         f.P1 = reader["p1"].ToString(); 
         objectList.Add(f1); 
        } 
        else if(ClassName == "Foo2") 
        { 
         /* Create and initialize Foo2 object*/ 
         objectList.Add(f2); 
        } 


       } 
       return objectList; 
      } 
      catch (Exception e) 
      { 

      } 
      finally 
      { 
       conn.Close(); 
      } 
     } 
    } 

    return null; 
} 

是否有更好的/優雅的方法?

編輯

什麼我忘了說是這樣的 - 我的最終目標是創建JSONAJAX從JavaScript調用。我的計劃是迭代Foo1和Foo2對象列表以爲每個請求創建Json數據。

我認爲我可以在存儲過程中創建JSON並將其作爲varchar(max)返回,並使用JSON2.js在客戶端創建JSOn對象。 我在這裏看到的缺點是varchar上8000字符限制的限制。

回答

0

我不是一個專家,不幸的是,但我想我得到你想要做的。我的建議(儘管它可能不是最好的)將創建一個數據類型的枚舉,然後在通用函數中搜索它的提交,然後你可以使用表名對照你輸入的字符串。

我用類似的方法用於存儲這種性質的信息時,它看起來像這樣...

功能:

public UInt32 getKeyCode(string Key) 
    { 
     Constants.KeyboardControls keynum; 
     if (Enum.TryParse<Constants.KeyboardControls>(Key, true, out keynum)) 
     { 
      return (UInt32)(keynum); 
     } 
     else 
     { 
      return new UInt32(); 
     } 
    } 

枚舉:

public enum KeyboardControls : uint 
    { 
     F1 = 0x70, 
     F2 = 0x71, 
     F3 = 0x72, 
     F4 = 0x73, 
     F5 = 0x74, 
     F6 = 0x75, 
     F7 = 0x76, 
     F8 = 0x77, 
     F9 = 0x78, 
     F10 = 0x79, 
     F11 = 0x7A, 
     F12 = 0x7B, 
     left = 0x25, 
     up = 0x26, 
     right = 0x27, 
     down = 0x28 
    } 

我希望這有助於在至少有一點,你可以在枚舉中列出任何對象,只要改變對象的類型就可以改變它的位置,而左邊則是非常多的字符串。

+0

你能解釋一下嗎?我沒有完全理解你的意思。 – Jeff 2013-02-16 00:03:45

+0

我沒有花時間去完全閱讀你的代碼,並且如果我這樣做的話不會很好理解它(這需要我花一個多小時才能分析),但是這聽起來像你剛纔的泛型函數,如果是這樣的話,對數據類型使用枚舉可能是有用的。例如,可以將4種類型的數據存儲在一個枚舉中,然後當您調用該函數時,您可以傳遞一個字符串,並對該字符串執行Enum.TryParse(),以查看它是否可以在枚舉中找到,然後你可以有一個對象,而不僅僅是一個字符串,它可以用在一些更健壯的方法中。 – XtrmJosh 2013-02-16 00:11:16

2

我不認爲你會購買太多試圖泛化這一點。在創建Foo1Foo2的過程之間唯一真正共同的部分是創建/關閉ConnectionDataReader。它們將在DataReader和該類之間有不同的SQL命令和不同的映射。

我的建議是要麼使用像NHibernate的或實體框架庫已經抽象了數據庫垃圾,或抽象掉的部分,並具有可創建從DataReaderFoo1Foo2實例工廠。否則,你將最終得到一堆開關,這些開關根據你要創建的對象的類型(這是你要下的道路)改變代碼,或者使用反射來自動將屬性映射到數據庫列。

+0

+1 - 如果完全成熟的ORM像NHibernate或EF太多,請看看Dapper http://code.google.com/p/dapper-dot-net/或Simple.Data - http: //simplefx.org/simpledata/docs/ – 2013-02-15 23:19:57

+0

@Dstanley&RussCam你們是對的。 GetData內部的switch語句不是我最初想做的事情。 – Jeff 2013-02-15 23:52:59

+0

我編輯了我的問題,包括我的總體目標來做到這一點 – Jeff 2013-02-16 00:00:41

相關問題