Get Dataset information in C# - c#

I have an Dataset (XSD) with many datatables. How can I get informations about this datatables? for example I want to get all columns and its captions from a specific datatable.
When I use dataset_X.datatable_Y.... there are no properties like "colums" and so on.
I only get "Equals", "GetDataTableSchema", "GetTypedSchema" and "Reference Equals".

You need to create an instance of your strongly typed DataSet.
For example:
var ds = new dataset_X();
DataColumnCollection columns = ds.datatable_Y.Columns;
or, if you want informations of a specific column, you can also use the auto generated property. Assuming there's a column with a name idSparePart, there's automatically a property idSparePartColumn.
DataColumn col = ds.datatable_Y.idSparePartColumn;
String columnName = col.ColumName;
Type t = col.DataType;
// and so on...

You can try with this code - based on GetXmlSchema
string schemaString = dataSet.GetXmlSchema();
Link : http://msdn.microsoft.com/en-us/library/41732z18.aspx

Related

Having a DataTable as a cell value of another DataTable in WPF

so my problem is that I want to display a table inside another table in WPF.
I use a DataTable in order to display some data and there is one column, in which I need to display another DataTable. I set AutoGenerateColumns="True". For a little testing, this is what I wrote (well, it works as expected):
var curDataTable = new DataTable();
curDataTable.Columns.Add("name" , typeof(string));
curDataTable.Columns.Add("number", typeof(int));
DataRow curRowData = curDataTable.NewRow();
curRowData[0] = "jones";
curRowData[1] = 90;
curDataTable.Rows.Add(curRowData);
Now, let's say I already have a filled DataTable _dataTable. I now want to display this _dataTable in my second column. This is what i would expect to work, but what does not work:
var curDataTable = new DataTable();
curDataTable.Columns.Add("name" , typeof(string));
curDataTable.Columns.Add("table", typeof(DataTable));
DataRow curRowData = curDataTable.NewRow();
curRowData[0] = "jones";
curRowData[1] = _dataTable;
curDataTable.Rows.Add(curRowData);
Has anyone an idea how to fix this?
Using nested DataTables won't work.
What you should do is to replace the outer DataTable with a custom type and bind to a custom collection property of this type in a DataGridTemplateColumn.
I don't think that nested DataTables are possible...
What you can do is create new column in '_datatable' with the name of "name"
_datatable.Columns.Add("name" , typeof(string)).SetOrdinal(0);
Using SetOrdinal(0) you can make "name" column first column. Now you maybe able to add new columns to it.
I hope it helps

Binding DataGridView to DataTable with ComboBox not working

I'm trying to create a DataGridView bound to a DataTable where one column is a ComboBox. The code runs but I get the following error after binding (not when data is bound): System.ArgumentException: DataGridViewComboBoxCell value is not valid.
In the DataGridView one of the columns is a DataGridViewComboBoxColumn that uses an enum (named structureType) as it's source:
// ColumnStructure
//
this.ColumnStructure.ValueType = typeof(structureType);
this.ColumnStructure.DataSource = Enum.GetValues(typeof(structureType));
this.ColumnStructure.HeaderText = "Structure";
this.ColumnStructure.Name = "ColumnStructure";
this.ColumnStructure.DataPropertyName = "Structure";
//
When I populate the DataGridView without using a DataTable, it works just fine:
structureType? structure = GetStructure(part);
dgvObjectTypes.Rows.Add(name, type, structure, count);
Now I would want to use a DataTable instead, but can't get it to work. The DataTable is created as follows:
DataTable table = new DataTable();
table.Columns.Add("Name", typeof(string));
table.Columns.Add("Type", typeof(string));
table.Columns.Add("Structure", typeof(DataGridViewComboBoxCell));
table.Columns.Add("Count", typeof(int));
Other columns work great but I can't get the "Structure" column to work. Here's how I've tried to create the combobox:
var cb = new DataGridViewComboBoxCell();
cb.ValueType = typeof(structureType);
cb.DataSource = Enum.GetValues(typeof(structureType));
cb.Value = (structureType)structure;
After that I just create the rows for the table and and set the table as datasource for the DataGridView:
table.Rows.Add(name, type, cb, count);
dgv.DataSource = table;
I've read a lot of posts where it has been stated that using enums in comboboxes causes problems (this for example: DataGridView linked to DataTable with Combobox column based on enum), but that doesn't seem to be the case here. I even tried to use explicitly typed arrays of strings but still get the same error. I think I'm doing something wrong with the DataGridViewComboBoxCell.
What could be the problem?
It seems like the step you are missing is providing the Names and Values for the CBO. The DataTable can store the value, and the DGV can display the related name, but you need to help provide the translation.
private enum structureType
{ None, Circle, Square, Pyramid}
...
dtStruct = new DataTable();
dtStruct.Columns.Add("Name", typeof(string));
dtStruct.Columns.Add("Type", typeof(string));
dtStruct.Columns.Add("Structure", typeof(structureType));
dtStruct.Columns.Add("Count", typeof(int));
// autogen columns == true
dgv2.DataSource = dtStruct;
// create DataSource as list of Name-Value pairs from enum
var cboSrc = Enum.GetNames(typeof(structureType)).
Select( x => new {Name = x,
Value = (int)Enum.Parse(typeof(structureType),x)
}
).ToList();
// replace auto Text col with CBO col
DataGridViewComboBoxColumn cb = new DataGridViewComboBoxColumn();
cb.ValueType = typeof(structureType);
cb.DataSource = cboSrc;
cb.DisplayMember = "Name"; // important
cb.ValueMember = "Value"; // important
cb.HeaderText = "Structure";
cb.DataPropertyName = "Structure"; // where to store the value
dgv2.Columns.Remove(dgv2.Columns[2]); // remove txt col
dgv2.Columns.Add(cb);
cb.DisplayIndex = 2;
// add data
dtStruct.Rows.Add("Ziggy", "Foo", structureType.Circle, 6);
The first part creates the DataTable, note that the Structure column type is structureType (or often int). The DataTable will be storing data, not DataGridViewComboBoxCell elements. In cases where the data comes from a database, that column would be int since structureType would not be a known type.
A DataSource is then created from the enum names and values. This provides the means for the control to show the name, yet store the value in the DataTable.
If the DGV is set to auto generate columns, you will need to replace the default TextBoxColumn with a ComboBoxColumn. This is being done after the DataSource has been set, but before any data is added. When the data comes from a DB (and so there is not usually an empty, typed table) you can use the ColumnAdded event to swap out one column for another.
The important thing when adding the CBO column is to set the ValueMember and DsiplayMember properties to provide the Value <-> Name translation and DataPropertyName so it knows where to store the selected value in the DataTable.

Copy DataTable from one DataSet to another

I'm trying to add to a new DataSet X a DataTable that is inside of a different DataSet Y.
If I add it directly, I get the following error:
DataTable already belongs to another DataSet.
Do I have to clone the DataTable and import all the rows to it and then add the new DataTable to the new DataSet? Is there a better/easy way to do it?
There are two easy ways to do this:
DataTable.Copy
Instead of DataTable.Clone, use DataTable.Copy to create a copy of your data table; then insert the copy into the target DataSet:
dataSetX.Tables.Add( dataTableFromDataSetY.Copy() );
DataSet.Merge
You could also use DataSet.Merge for this:
dataSetX.Merge(dataTableFromDataSetY);
Note, however, that if you are going to use this method, you might want to make sure that your target DataSet doesn't already contain a table with the same name:
If the target DataSet doesn't contain a table by the same name, a fresh copy of the table is created inside the data set;
If a table by the same name is already in the target data set, then it will get merged with the one passed to Merge, and you end up with a mix of the two.
Use this generic function
public DataTable CopyDataTable(DataTable dtSource, int iRowsNeeded)
{
if (dtSource.Rows.Count > iRowsNeeded)
{
// cloned to get the structure of source
DataTable dtDestination = dtSource.Clone();
for (int i = 0; i < iRowsNeeded; i++)
{
dtDestination.ImportRow(dtSource.Rows[i]);
}
return dtDestination;
}
else
return dtSource;
}
Suppose you want to copy first table of sourceSet to destinationSet.
Call it like
DataTable destinationTable = CopyDataTable(sourceSet.Tables[0], sourceSet.Tables[0].Rows.Count);
DataSet destinationSet = new DataSet();
destinationSet.Tables.Add(destinationTable);
This should work for you
X.Tables.Add(Y.Tables[<tablename|index>].Copy());
IEnumerable<DataRow> query = from sourceTbl in sourceTbl.AsEnumerable()
where [any condition you want]
select order;
DataTable boundTable = query.CopyToDataTable<DataRow>();
I am not sure If i understood your question properly.Hope this code helps

extract data from a dataset

I have a dataset that gets populated from a stored proc in sql server. I have a column that has lets say has a set of values. I do not know what those values are. All I know is that they of the type "string". I want to extract all the distinct values from that column.
You can use a DataView and set its RowFilter to the desired condition:
var view = new DataView(dataset.Tables["Table"]);
view.RowFilter = "Column = 42";
UPDATE: based on your updated question, you can use LINQ:
var table = dataset.Tables["Table"].AsEnumerable();
var distinctValuesForColumn =
table.Select(row => (string)row["Column"]).Distinct();
You can simply use Select method of the DataTable :
DataRow[] extractedRows =
yourDataSet.Tables["YourTableName"].Select("YourColumnName = 123");
You can also use Linq to query your datatables. Here is a link to some examples on the MS site - http://msdn.microsoft.com/en-us/vbasic/bb688086.aspx
I hope below statement will serve your purpose
ds.Tables["TableName"].DefaultView.ToTable( true, "columnName"); //For Dataset (true means distinct)
OR
`ds.Tables[0].DefaultView.ToTable( true, "columnName");
//For Dataset where tableindex is 0
OR
dt.DefaultView.ToTable( true, "columnName"); //For Datatable
//Syntax is like Datatable.DefaultView.ToTable( Distinct true/false, “ColumnName”);
MSDN : http://msdn.microsoft.com/en-us/library/wec2b2e6.aspx

How can I add the column data type after adding the column headers to my datatable?

Using the code below (from a console app I've cobbled together), I add seven columns to my datatable. Once this is done, how can I set the data type for each column? For instance, column 1 of the datatable will have the header "ItemNum" and I want to set it to be an Int. I've looked at some examples on thet 'net, but most all of them show creating the column header and column data type at once, like this:
loadDT.Columns.Add("ItemNum", typeof(Int));
At this point in my program, the column already has a name. I just want to do something like this (not actual code):
loadDT.Column[1].ChangeType(typeof(int));
Here's my code so far (that gives the columns their name):
// get column headings for datatable by reading first line of csv file.
StreamReader sr = new StreamReader(#"c:\load_forecast.csv");
headers = sr.ReadLine().Split(',');
foreach (string header in headers)
{
loadDT.Columns.Add(header);
}
Obviously, I'm pretty new at this, but trying very hard to learn. Can someone point me in the right direction? Thanks!
You should be able to assign the column's data type property so long as there is no data stored in that column yet:
CODE:
loadDT.Column[1].DataType = typeof(int);
visual studio not allows to change type of a column has some data,
u must create a new column with ur ideal type and copy data from specified column to new column
DataTable DT = new DataTable();
DT = somsdata ;
DT.columns.Add("newcol",object);
foreach(datarow dr in DT.rows)
dr.itemarray["newcolumn"] = dr.itemarray["oldColumn"];

Categories