2011-05-19 17 views
1

非常沮喪這裏... 我通常可以在網上找到的.Net某種複雜的問題一個答案的地方,但是這一次我摸不透。 我處於一種場景,我必須將LINQ的結果轉換爲實體查詢,然後才能將數據轉換爲數據集,以便現有的業務邏輯可以處理這些數據,而且我無法找到適合此目的的單個工作解決方案。我嘗試了基本的方法,如EntityCommand生成一個閱讀器,但這一個不工作,因爲DataTable.Load()thorws一個excpetion(讀者生成的EntityCommand不支持GetSchemaTable())。將實體模型轉換爲數據集 - 可以這樣做嗎?

我也嘗試了更多的[假設]友好的方法,如實體IDataReader(http://l2edatareaderadapter.codeplex.com/),但這一個拋出異常,有很少的文檔,並沒有被觸及,因爲2008.

我發現的另一種方法是在這裏(http://blogs.msdn.com/b/alexj/archive/2007/11/27/hydrating-an-entitydatareader-into-a-datatable-part-1 .aspx),但沒有代碼的工作副本;只有片段。

我覺得很難相信,首先MS的就不會提供這種向後兼容項目開箱,第二,它不會一直由社區製作無論是。

我願意在商業解決方案看,以及(如果可用)。

Thx!

回答

0

這可能不是最大的解決方案,但如果你的方案只有一個或兩個表,你需要添加到DataSet,爲什麼不直接自行建立。

var result = db.YourTable; // get your Linq To Entities result. 

DataSet ds = new DataSet(); 
DataTable tbl = new DataTable(); 
tbl.Columns.Add("col1", typeof(string)); 
tbl.Columns.Add("col2", typeof(int)); 

foreach (var r in result) 
{ 
    var row = tbl.NewRow(); 
    row[0] = r.Col1; 
    row[1] = r.Col2; 

    tbl.Rows.Add(r); 

}

ds.Tables.Add(TBL);

的col1和col2的來自你的Linq到實體對象,您可以創建你需要這樣的表並返回數據集中。

+0

THX多米尼克。嘗試了類似的東西。 一個巨大的問題 - 大型實體(即包含大量數據)。爲了解決這個問題,我有一個遞歸方法沿着實體樹進行,併爲它開始複製的每一個新的級別開始一個新的副本(在一個新的線程中),但是猜測--DataTable對象不是線程安全的。他們的內部索引很容易被破壞。只要你嘗試從多個線程向它們添加行,你會得到像http://stackoverflow.com/questions/450675/datatable-internal-index-is-corrupted這樣的異常。 – 2011-05-21 12:55:56

+0

我不知道DataTable不是線程安全的。在這種情況下,我想最簡單的做法是從SqlCommand填充DataSet,而不是從實體傳遞。 – 2011-06-02 09:26:52

3

您可以將結果轉換成一個列表,並使用下面的列表轉換爲一個數據表。

public DataTable ConvertToDataTable<T>(IList<T> data) 
    { 
     PropertyDescriptorCollection properties = 
      TypeDescriptor.GetProperties(typeof(T)); 
     DataTable table = new DataTable(); 
     foreach (PropertyDescriptor prop in properties) 
      table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType); 
     foreach (T item in data) 
     { 
      DataRow row = table.NewRow(); 
      foreach (PropertyDescriptor prop in properties) 
       row[prop.Name] = prop.GetValue(item) ?? DBNull.Value; 
      table.Rows.Add(row); 
     } 
     return table; 

    } 

http://social.msdn.microsoft.com/Forums/br/csharpgeneral/thread/6ffcb247-77fb-40b4-bcba-08ba377ab9db

希望這有助於

Preetam

+0

有趣的方法。將不得不嘗試並回復你。 Thx的想法。 – 2012-12-01 00:41:17

0

這是一個靈活的代碼,並應處理滿足你的需要:

public DataTable LINQToDataTable<T>(IEnumerable<T> varlist) 
    { 
     DataTable dtReturn = new DataTable(); 
     // column names 
     PropertyInfo[] oProps = null; 
     if (varlist == null) return dtReturn; 
     foreach (T rec in varlist) 
     { 
      // Use reflection to get property names, to create table, Only first time, others will follow 
      if (oProps == null) 
      { 
       oProps = ((Type)rec.GetType()).GetProperties(); 
       foreach (PropertyInfo pi in oProps) 
       { 
        Type colType = pi.PropertyType; 
        if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>))) 
        { 
         colType = colType.GetGenericArguments()[0]; 
        } 

        dtReturn.Columns.Add(new DataColumn(pi.Name, colType)); 
       } 
      } 

      DataRow dr = dtReturn.NewRow(); 
      foreach (PropertyInfo pi in oProps) 
      { 
       dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue 
       (rec, null); 
      } 

      dtReturn.Rows.Add(dr); 
     } 

     return dtReturn; 
    }