Methods to convert a Linq output query to a DataTable
The following extension method is a sample of how to convert a Linq output query to a DataTable. This example creates and returns a new DataTable object.
public static class ExtensionMethods { public static DataTable ToADOTable<T>(this IEnumerable<T> varlist) { // create a new instance of a DataTable object DataTable dtReturn = new DataTable(); // column names PropertyInfo[] oProps = null; if (varlist == null) return dtReturn; // iterate through each of the items (rows) in the object passed in. foreach (T rec in varlist) { // Use reflection to get property names, to create table columns, // Only first time, others will follow if (oProps == null) { // get all the properties of the current record. oProps = ((Type)rec.GetType()).GetProperties(); // iterate through each of the row properties. 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; } }
The following sample takes the output from a Linq query and outputs it to an existing DataTable. Only columns that match are added to the destination table. Columns in the destination table that don't exist in the source are left as null.
public static class ExtensionMethods { public static void ToADOTable<T>(this IEnumerable<T> varlist, DataTable tblOutput) { do { if (varlist == null) break; if (tblOutput == null) break; if (varlist == tblOutput) { throw new System.Exception("In call to ToADOTable(DataTable), source and destination are the same!"); } // column names of the source Type oTypeInput = null; // iterate through each of the rows in the input table. foreach (T recInput in varlist) { // create a new row. DataRow drOutput = tblOutput.NewRow(); // initialize all the column values csClasses.Classes.Utility.ClearRow(drOutput); if (oTypeInput == null) { oTypeInput = (Type)recInput.GetType(); } System.Diagnostics.Debug.Indent(); // set the column values. // iterate through each of the columns in the destination table. foreach (DataColumn colOutput in drOutput.Table.Columns) { //if (col.ReadOnly) continue; // get the column name. string strColumnName = colOutput.ColumnName; Type oTypeOutput = colOutput.DataType; if (oTypeOutput == typeof(byte[])) continue; // put this here to ignore timestamp column. May need to revisit later. //System.Diagnostics.Debug.WriteLine(string.Format("column name: '{0}'", strColumnName)); // look for the column in the source PropertyInfo piInputColumn = oTypeInput.GetProperty(strColumnName); // if not found, skip to next column if (piInputColumn == null) continue; MethodInfo miNullTest = oTypeInput.GetMethod(string.Format("Is{0}Null", strColumnName)); if (miNullTest != null) { object oNullTestResult = miNullTest.Invoke(recInput, new object[] { }); if (oNullTestResult.ToBoolean()) { drOutput[strColumnName] = DBNull.Value; continue; } } // get the object value. object objVal = piInputColumn.GetValue(recInput, null); // set the value in the column drOutput[strColumnName] = objVal ?? DBNull.Value; } System.Diagnostics.Debug.Unindent(); // add the row to the table. tblOutput.Rows.Add(drOutput); } // accept the changes to the output table. tblOutput.AcceptChanges(); } while (false); } } }