I am using this code to get data from a dataReader into a DataTable which can then be serialised.
However, it looks like any column with a null value isnt being written to the xml.
I cant see the issue.
This is my entire class, and im calling this method
Process(IDataReader data, string filePath)
Im certain that this works, because i have used it to serialise dataTables before
Process(DataTable table, string filePath)
So i think it must be in the "GetDataTableFromSqlDataReader" method??
public class DataSerialisation
{
public static DataRow GetFirstDataRow(string xmlFilePath)
{
return GetDataTable(xmlFilePath).Rows[0];
}
public static DataTable GetDataTable(string xmlFilePath)
{
DataSet ds = new DataSet();
ds.ReadXml(xmlFilePath);
return ds.Tables[0];
}
private static DataTable GetDataTableFromSqlDataReader(IDataReader dr)
{
DataTable dtSchema = dr.GetSchemaTable();
DataTable dt = new DataTable();
ArrayList listCols = new ArrayList();
if (dtSchema != null)
{
foreach (DataRow drow in dtSchema.Rows)
{
string columnName = Convert.ToString(drow["columnName"]); //drow["columnName"].ToString();
DataColumn column = new DataColumn(columnName, (Type) (drow["DataType"]));
//column.ColumnName = columnName;
//column.Unique = (bool) (drow["IsUnique"]);
column.AllowDBNull = (bool) (drow["AllowDBNull"]);
//column.AutoIncrement = (bool) (drow["IsAutoIncrement"]);
//column.AutoIncrement = (bool) (drow["IsAutoIncrement"]);
listCols.Add(column);
dt.Columns.Add(column);
}
while (dr.Read())
{
DataRow dataRow = dt.NewRow();
for (int i = 0; i < listCols.Count; i++)
dataRow[((DataColumn) listCols[i])] = dr[i];
dt.Rows.Add(dataRow);
}
}
return dt;
}
public static void Process(IDataReader data, string filePath)
{
Process(GetDataTableFromSqlDataReader(data), filePath);
}
public static void Process(DataTable table, string filePath)
{
DataSet ds = new DataSet();
ds.Tables.Add(table.Clone());
foreach (DataRow row in table.Rows)
{
DataRow newRow = ds.Tables[0].NewRow();
for (int col = 0; col < ds.Tables[0].Columns.Count; col++)
newRow[col] = row[col];
ds.Tables[0].Rows.Add(newRow);
}
ds.WriteXml(new StreamWriter(filePath));
}
}
Related
I am trying to load back values from a CSV to my class. Then display the values to my datatable. However, I get the error even after my values have been loaded into the class and placed inside the intended columns (See Figure 1). The error occurred at dt.Rows.Add(dr);. Below is my code:
public Newdatagrid()
{
InitializeComponent();
//Do datatable
ds = new DataSet();
dt = new DataTable();
dt.Columns.Add("Bus Model", typeof(string));//0
dt.Columns.Add("Bus Type", typeof(string));//1
dt.Columns.Add("Mileage", typeof(string));//2
if (Savestate.vehnochange_list.Count > 0)
{
foreach (DataRow dr in dt.Rows)
{
dr["Bus Model"] = Savestate.busmodel_list[Savestate.busmodel_list.Count];//0
dr["Bus Type"] = Savestate.bustype_list[Savestate.bustype_list.Count];//1
dr["Mileage"] = Savestate.busmileage_list[Savestate.busmileage_list.Count];//2
}
dt.Rows.Add(dr);
this.dataGridView2.DataSource = dt;
}
}
I think you want something like this:
public Newdatagrid()
{
InitializeComponent();
//Do datatable
ds = new DataSet();
dt = new DataTable();
dt.Columns.Add("Bus Model", typeof(string));//0
dt.Columns.Add("Bus Type", typeof(string));//1
dt.Columns.Add("Mileage", typeof(string));//2
if (Savestate.vehnochange_list.Count > 0)
{
for (int i=0; i < Savestate.vehnochange_list.Count; ++i)
{
DataRow dr = dt.NewRow();
dr["Bus Model"] = Savestate.busmodel_list[i];//0
dr["Bus Type"] = Savestate.bustype_list[i];//1
dr["Mileage"] = Savestate.busmileage_list[i];//2
dt.Rows.Add(dr);
}
this.dataGridView2.DataSource = dt;
}
}
I want to continue to add data to datatable that already contains data.
In this method, it was get data like: dt = { 1, 2 }.
public class GetRowOne()
{
// some code
if(contains == null)
{
DataRow dr = dt.NewRow();
string[] array1 = lstHeader[1].ToArray();
for (int i = 0; i < 8; i++)
dr[i] = array1[i];
}
// some code
}
dt.Rows.Add(dr.ItemArray);
Now, in another method, I also create and run same like this code.
public class GetRowTwoAndThree()
{
// some code
DataRow dr = dt.NewRow();
string[] array1 = lstHeader[1].ToArray();
for (int i = 0; i < 8; i++)
dr[i] = array1[i];
// some code
}
dt.Rows.Add(dr.ItemArray);
It return new values in dt is: dt = { 4, 5 }
I think error at like: DataRow dr = dt.NewRow(); or line: dt.Rows.Add(dr.ItemArray);
You will look: when dt.Rows.Add(dr.ItemArray). All before data will null, it only add new values to dt.
I want dt save old data and new data, it should be:
dt = { 1, 2, 3, 4 }
Store Data in ViewState["OldData"] and after adding new row again store dt in ViewState["OldData"].
If in same page you are calling method then store that in viewstate, you can also store in session or create get set method for that datatable
DataTable dt{get; set;}
EDIT-:
DataTable dt = new DataTable();
public Form1()
{
InitializeComponent();
dt.Columns.Add("Column1");
dttest = dt;
}
public void GetRowOne()
{
DataRow dr = dt.NewRow();
dr["Column1"] = "Test";
dt.Rows.Add(dr);
dttest = dt;
}
DataTable dttest { get; set; }
private void button1_Click(object sender, EventArgs e)
{
GetRowOne();
}
My Datagrid is filled with the right number of rows, but there are no data show.
All the row are display empty cols.
What could be the reason for that ?
basedon
It is the first time I use a datagridview.
public void BindDataGridView(DataGridView dgv, Hashtable ht) {
DataSet ds = new DataSet();
DataTable dt = ds.Tables.Add("test");
//now build our table
dt.Columns.Add("col1", typeof(string));
dt.Columns.Add("col2", typeof(Int32));
IDictionaryEnumerator enumerator = ht.GetEnumerator();
DataRow row = null;
while (enumerator.MoveNext()) {
string index = (string)enumerator.Key; // boekingsREf
MyClass a = (MyClass)enumerator.Value;
row = dt.NewRow();
row["col1"] = index;
row["col2"] = a.number;
dt.Rows.Add(row);
}
//dgv.DataSource = ds.Tables[0];
dgv.DataSource = ds.Tables[0];
}
First example:
public Form1()
{
InitializeComponent();
Hashtable ht = new Hashtable();
ht[1] = "One";
ht[2] = "Two";
ht[3] = "Three";
BindDataGridView(dataGridView1, ht);
}
public void BindDataGridView(DataGridView dgv, Hashtable ht)
{
DataSet ds = new DataSet();
DataTable dt = ds.Tables.Add("test");
//now build our table
dt.Columns.Add("col1", typeof(int));
dt.Columns.Add("col2", typeof(string));
foreach (DictionaryEntry dictionaryEntry in ht)
{
int index = (int)dictionaryEntry.Key;
string value = (string)dictionaryEntry.Value;
DataRow row = dt.NewRow();
row["col1"] = index;
row["col2"] = value;
dt.Rows.Add(row);
}
dgv.DataSource = ds.Tables[0];
}
Second example:
Assuming your MyClass is
public class MyClass
{
public int number { get; set; }
static public implicit operator MyClass(int value)
{
return new MyClass() { number = value };
}
}
and the hashtable is (reverse keys/values)
Hashtable ht = new Hashtable();
ht["One"] = 1;
ht["Two"] = 2;
ht["Three"] = 3;
and you change this line from your post code
MyClass a = (int)enumerator.Value;
For Performance improvement I want to convert datatable to datareader. I can not do that through query. So is there any other way to do so?
I know this is old, but the answers here seem to have missed the point of the OPs question.
DataTables have a method called CreateDataReader which will allow you to convert a DataTable to a DbDataReader object. In this case a DataTableReader.
DataTable table = new DataTable();
//Fill table with data
//table = YourGetDataMethod();
DataTableReader reader = table.CreateDataReader();
I should point out that this will not increase performance since you should be using one or the other.
Here are some more resources on the matter:
DataReader Vs DataTable
Is datareader quicker than dataset when populating a datatable?
For example
public DataTable ConvertDataReaderToDataTable(SqlDataReader dataReader)
{
DataTable datatable = new DataTable();
DataTable schemaTable = dataReader.GetSchemaTable();
try
{
foreach (DataRow myRow in schemaTable.Rows)
{
DataColumn myDataColumn = new DataColumn();
myDataColumn.DataType = myRow.GetType();
myDataColumn.ColumnName = myRow[0].ToString();
datatable.Columns.Add(myDataColumn);
}
while (dataReader.Read())
{
DataRow myDataRow = datatable.NewRow();
for (int i = 0; i < schemaTable.Rows.Count; i++)
{
myDataRow[i] = dataReader[i].ToString();
}
datatable.Rows.Add(myDataRow);
myDataRow = null;
}
schemaTable = null;
return datatable;
}
catch (Exception ex)
{
Error.Log(ex.ToString());
return datatable;
}
}
Use DataTable constructor,
DataTable table = new DataTable();
//Fill table with data
DataTableReader reader = new DataTableReader(table);
Good Look!
public DataTable GetTable(IDataReader _reader)
{
DataTable dataTable1 = _reader.GetSchemaTable();
DataTable dataTable2 = new DataTable();
string[] arrayList = new string[dataTable1.Rows.Count];
for (int i = 0; i < dataTable1.Rows.Count; i++)
{
DataColumn dataColumn = new DataColumn();
if (!dataTable2.Columns.Contains(dataTable1.Rows[i]["ColumnName "].ToString()))
{
dataColumn.ColumnName = dataTable1.Rows[i]["ColumnName "].ToString();
dataColumn.Unique = Convert.ToBoolean(dataTable1.Rows[i]["IsUnique "]);
dataColumn.AllowDBNull = Convert.ToBoolean(dataTable1.Rows[i]["AllowDBNull "]);
dataColumn.ReadOnly = Convert.ToBoolean(dataTable1.Rows[i]["IsReadOnly "]);
dataColumn.DataType = (Type)dataTable1.Rows[i]["DataType "];
arrayList[i] = dataColumn.ColumnName;
dataTable2.Columns.Add(dataColumn);
}
}
dataTable2.BeginLoadData();
while (_reader.Read())
{
DataRow dataRow = dataTable2.NewRow();
for (int j = 0; j < arrayList.Length; j++)
{
dataRow[arrayList[j]] = _reader[arrayList[j]];
}
dataTable2.Rows.Add(dataRow);
}
_reader.Close();
dataTable2.EndLoadData();
return dataTable2;
}
In normal WinForm application you can do that:
DataTable dataTable = new DataTable();
dataTable = dataGridRecords.DataSource;
but how to do that with the WPF datagrid?
dataTable = dataGridRecords.ItemsSource;
won't work either.
In WPF you don't do this
DataGrid.ItemsSource = DataTable;
Instead you do
DataGrid.ItemsSource = DataTable.AsDataView();
In order to get DataTable back you can do something like this
public static DataTable DataViewAsDataTable(DataView dv)
{
DataTable dt = dv.Table.Clone();
foreach (DataRowView drv in dv)
dt.ImportRow(drv.Row);
return dt;
}
DataView view = (DataView) dataGrid.ItemsSource;
DataTable table = DataViewAsDataTable(view)
You don't need the DataViewAsDataTable method. Just do the following:
DataTable dt = ((DataView)dataGrid1.ItemsSource).ToTable();
try this
public static DataTable DataGridtoDataTable(DataGrid dg)
{
dg.SelectAllCells();
dg.ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;
ApplicationCommands.Copy.Execute(null, dg);
dg.UnselectAllCells();
String result = (string)Clipboard.GetData(DataFormats.CommaSeparatedValue);
string[] Lines = result.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);
string[] Fields;
Fields = Lines[0].Split(new char[] { ',' });
int Cols = Fields.GetLength(0);
DataTable dt = new DataTable();
for (int i = 0; i < Cols; i++)
dt.Columns.Add(Fields[i].ToUpper(), typeof(string));
DataRow Row;
for (int i = 1; i < Lines.GetLength(0)-1; i++)
{
Fields = Lines[i].Split(new char[] { ',' });
Row = dt.NewRow();
for (int f = 0; f < Cols; f++)
{
Row[f] = Fields[f];
}
dt.Rows.Add(Row);
}
return dt;
}