2013-08-29 45 views
2

我已經贏得與實體框架的形式的應用程序。在我的DbContext中,我有兩個實例:表;列。在我的數據訪問層我有以下代碼真正的通用實現

public static class DataLoader 
{ 
    private static WdmEntities _context; 

    public static List<T> GetTable<T>() where T : class 
     { 
      List<T> res = new List<T>(); 

      using (_context = new WdmEntities()) 
      { 

       try 
       { 
        res = _context.Set<T>().ToList(); 
       } 
       catch 
       { 
       } 
      } 

      return res; 
     } 
} 

Form.cs我有以下的

availableTablesListBox.+= availableTablesListBox_SelectedIndexChanged; 

void availableTablesListBox_SelectedIndexChanged(object sender, EventArgs e) 
{ 
    //here i need to write code, that call GetTable<T> from DataLoader 
    //according to the SelectedIndex of availableTablesListBox 
} 

事件處理程序,但我可以寫(不是真的通用)

if (availableTablesListBox.SelectedIndex == 1) 
    myDataGrid.DataSource = DataLoader.GetTable<tables>(); 
else 
    myDataGrid.DataSource = DataLoader.GetTable<columns>(); 

我想要寫一行代碼

myDataGrid.DataSource = DataTable.GetTable<WHAT WRITE HERE>(); 
+0

「availableTablesListBox」的數據源是什麼? – SynerCoder

回答

3

泛型被烘烤到IL中,所以沒有單一的WHAT WRITE HERE;您將不得不使用問題中的代碼,或者使用基於傳遞Type實例的非泛型實現。

在一推,你可以使用:

myDataGrid.DataSource = availableTablesListBox.SelectedIndex == 1 
    ? (IList)DataLoader.GetTable<tables>() 
    : (IList)DataLoader.GetTable<columns>(); 

,但是這是...不必要的令人費解。

坦率地說,當前的實現將做的工作,除了:

  • 沒有吞下例外 - 一個catch這忽略了一個事實,事情失敗簡直是一個非常糟糕的主意
  • 調用ToList()這裏強制它加載整個未過濾的表格;這是通常一個壞主意

如果你想實現一個基於Type執行,你可以使用非通用Set(Type)方法,而不是Set<T>方法。

1

它應該是這樣的:

public static readonly MethodInfo getTableT = ((Func<List<object>>)DataLoader.GetTable<object>) 
                .Method 
                .GetGenericMethodDefinition(); 

(這些線路我們得到您的GetTable<T>MethodInfo不使用字符串,更多的重構友好)

然後

Type[] types = new[] { typeof(tables), typeof(columns) }; 
myDataGrid.DataSource = getTableT.MakeGenericMethod(types[availableTablesListBox.SelectedIndex]) 
           .Invoke(null, null); 

顯然,你必須使用反射來完成它,因爲正如Gravell所說,泛型在編譯時被解決,所以你不能「構建」一個新的通用在運行時沒有反射。

+0

在這裏跳入MakeGenericMethod是一個壞主意 - 最好使用基於Type的實現 –

+0

@MarcGravell我已經忘記了Set(Type)過載。 – xanatos

+0

.Invoke(null,null) – isxaker

相關問題