I have below code, where in I am creating a dataset based on a query to Oracle mdb.
....
**OracleDataAdapter adapter = new OracleDataAdapter(sqlstr, conn);
OracleCommandBuilder builder = new OracleCommandBuilder(adapter);
DataSet dataset = new DataSet();
adapter.Fill(dataset);**
DataTable dataTable = dataset.Tables[0];
....
I would like to have the highlighted code in a loop, and then add the dataset objects to a common datatable outside the loop.
Do I need to use datatable.Merge()? The resultset in 'n' datasets need to be combined into a single DataTable, hence I am not sure Merge is the right way.
How can this be implemented?
Thanks
Presumably you are creating a new 'sqlstr' for each query to the Oracle mdb? If so you can create a list to put all your sqlstr into and then have a for loop to cycle through them like this:
List<string> sqlstrings = new List<string>();
//add your sqlstr's here
DataSet dataset = new DataSet();
for(int i = 0; i < sqlstrings.count; i++)
{
OracleDataAdapter adapter = new OracleDataAdapter(sqlstrings[i].ToString(), conn);
OracleCommandBuilder builder = new OracleCommandBuilder(adapter);
adapter.Fill(dataset.Tables[i]);
}
This will get all of your queries into 1 dataset with multiple tables. You can then create a data relation between all the tables as per here: http://msdn.microsoft.com/en-us/library/ay82azad(v=vs.110).aspx.
However, if you want to create just 1 DataTable then you can use 'Merge' as per the link supplied by Mithrandir. Of course, you would need to add this into the loop above and account for the first run (you can't merge table 1 with nothing). Create a new DataTable before the loop and do something like:
if(i > 0)
{
dtBigTable.Merge(dataset.Tables[i]);
}
else
{
//First table
dtBigTables = dataset.Tables[0]
}
Note: this is untested code. It's just to give you an idea and something to play with.
Related
Is it possible to add a row to the middle of an existing dataset with c#? I've done a lot of searching and haven't been able to find anything on how to do this. What have I tried? I've tried searching a lot and haven't found anything like an 'insertAt' method for datasets.
Thanks
Mike
The DataSet consists of a collection of DataTable objects so I assume that you are talking about a Datatable, right? If so, it has an InsertAt method:
DataTable dt = dataset.Tables[0]; //Get first datatable from dataset
DataRow row = dt.NewRow();
//fill row
dt.Rows.InsertAt(row,3); //Insert at index 3
DataSet does not have a rows collection, so you can't add a row to it at all.
You can insert a row by index into a DataTable object using DataTable.Rows.InsertAt(row, i). If the table is in a DataSet, your syntax would be DataSet.Tables[i].Rows.InsertAt(row, 0)
In my opinion (though this could take a lot of time), you can create an array or a list array then transfer all the data there from your dataset through for loop or any loop...then put an if statement inside to check where you want to put your extra data like this:
List<string> arrayList = dataset;// i know this is not possible just showing you that you have to put all your data from dataset to array:)
List <string> newList = new List<string>();//its up to you if you want to put another temporary array or you could simply output your data from the loop.
//THE LOOP
for(int i = 0; i<=arrayList.Count(); i++){
if(i == x)//x is the index or you may change this statement its up to you
{
//do the print or pass the data to newList
newList.add(arraList[i]);//not sure about this. its been a while since the last time i use this array list..
}
}
another way is customize your query(if your pulling out some data from database)
happy coding:)
Here's a short sample of doing it:
class Program
{
static void Main(string[] args)
{
DataSet ds = new DataSet();
DataTable dt = ds.Tables.Add("Table");
dt.Columns.Add("Id");
for (int i = 0; i < 10; i++)
{
dt.Rows.Add(new object[]{i});
}
var newRow=dt.NewRow();
newRow.ItemArray=new string[]{(dt.Rows.Count/2).ToString()+".middle"};
dt.Rows.InsertAt(newRow, dt.Rows.Count / 2);
}
}
I've been using ORM's for so long, I appear to have forgotten most of my basic data handling skills in dotnet :(
Is it possibly to do something like this?
DataSet ds = new DataSet();
var compiledConnection = new SqlConnection(cDbConnectionString);
SqlDataAdapter daChart = new SqlDataAdapter("select * from Chart", compiledConnection);
daChart.Fill(ds, "chart");
if (ds.Tables["chart"].Rows.Count > 0)
{
var sourceConnection = new SqlConnection(sourceDbConnectionString);
SqlDataAdapter daSource = new SqlDataAdapter("select * from source", sourceConnection);
daSource.Fill(ds, "source");
DataRelation chart_source = new DataRelation("dr", ds.Tables["chart"].Columns["intItemId"],
ds.Tables["source"].Columns["intRowId"], false);
ds.Relations.Add(chart_source);
}
And then use one of the columns in the table "chart" to order the data in the table "source" across the datarelation?
(Before anyone asks, these two tables are in separare instances of SqlServer on separate sites, so just pulling the data as one table is not a straightforward task. Hence this approach)
Cheers,
Matt
That just creates the equivalent of a foreign key. You seem to want the equivalent of an INNER JOIN.
In addition to creating the relationship, it requires adding all the columns of one to the other, loops to fill in the rows and GetParentRows. MS has some good starting point code:
http://support.microsoft.com/kb/326080
EDIT. You could also do a SQL version, by creating a linked server and using 4 part names [server].[database].[owner].[table]
Thanks for the suggestion, but I discovered you can do it with LINQ rather more easily:
DataTable source = ds.Tables["source"];
DataTable chart = ds.Tables["chart"];
var joinedTable =
from s in source.AsEnumerable()
join c in chart.AsEnumerable()
on s.Field<Int64>("intRowId") equals
c.Field<Int64>("intItemId")
select new
{
intRowId = s.Field<Int64>("intRowID"),
strTitle = s.Field<string>("strTitle"),
intWeight = c.Field<Int64>("intWeight")
};
var sortedTable = from j in joinedTable
orderby j.intWeight descending
select j;
I use C#. I fill a dataset with the result of sql query. Suppose ds is my dataset:
Dataset ds = new Dataset();
ds = GetTablesFromDataBase("Select * from Order, Select * from OrderDetails, Select * from Product");
After running the code above, my dataset contains three tables named Table, Table1, Table2. But I want my dataset table names to be the same as database tables names like: Order, OrderDetails, Product. Is there any way to write query or code, so that dataset table names become the same as database table names?
Please, don't propose the code below to change the table names of a dataset:
Dataset.TableName = "RequiredTableName";
You can use typed datasets or tablemapping
something like this
SqlDataAdapter da = new SqlDataAdapter(...);
DataSet ds = new DataSet();
DataTableMapping dtm1, dtm2, dtm3;
dtm1 = da.TableMappings.Add("Table", "Employees");
dtm2 = da.TableMappings.Add("Table1", "Products");
dtm3 = da.TableMappings.Add("Table2", "Orders");
da.Fill(ds);
you should probably use the DataTable class instead. Here is the mSDN reference for the same: http://msdn.microsoft.com/en-us/library/system.data.datatable.aspx
It lets you define all the properties that you want plus give you lot more functions to work with the table.
and since you seem to like having all the tables in one class I would suggest you create a DTO that basically resembles whatever property you wanted to use of the DataSet class and add IList as one of the properties of this DTO.
Hope that makes sense and helps you.
ds.Tables[0].TableName = "Required Table Name";
ds.Tables[1].TableName = "Required Table Name";
ds.Tables[2].TableName = "Required Table Name";
You can use this method.
You could return the names of the tables with an separate select.
SELECT 'Employees','Orders';
SELECT * FROM Employees;
SELECT * FROM Orders;
(you could also select the Tablenames from the global systemtables...)
Then you can set the Tablenames in your DataSet automatically:
for (int cIdx = 0; cIdx < ds.Tables[0].Columns.Count; ++cIdx) {
int tIdx = cIdx + 1;
if (tIdx >= ds.Tables.Count) {
break;
}
ds.Tables[tIdx].TableName = ds.Tables[0].Rows[0][cIdx].ToString().Trim();
}
ds.Tables.RemoveAt[0];
This is also only a workaround, but I don't know a better way.
If I have 2 DataTables (dtOne and dtTwo) and I want to merge them and put them in another DataTable (dtAll). How can I do this in C#? I tried the Merge statement on the datatable, but this returns void. Does Merge preserve the data? For example, if I do:
dtOne.Merge(dtTwo);
Does dtOne change or does dtTwo change and if either one changes, do the changes preserve?
I know I can't do this because Merge returns void, but I want to be able to store the Merger of both dtOne and dtTwo in dtAll:
//Will Not work, How do I do this
dtAll = dtOne.Merge(dtTwo);
The Merge method takes the values from the second table and merges them in with the first table, so the first will now hold the values from both.
If you want to preserve both of the original tables, you could copy the original first, then merge:
dtAll = dtOne.Copy();
dtAll.Merge(dtTwo);
Instead of dtAll = dtOne.Copy(); in Jeromy Irvine's answer you can start with an empty DataTable and merge one-by-one iteratively:
dtAll = new DataTable();
...
dtAll.Merge(dtOne);
dtAll.Merge(dtTwo);
dtAll.Merge(dtThree);
...
and so on.
This technique is useful in a loop where you want to iteratively merge data tables:
DataTable dtAllItems = new DataTable();
foreach(var item in items)
{
DataTable dtItem = getDataTable(item); // some function that returns a data table
dtAllItems.Merge(dtItem);
}
dtAll = dtOne.Copy();
dtAll.Merge(dtTwo,true);
The parameter TRUE preserve the changes.
For more details refer to MSDN.
DataTable dtAll = new DataTable();
DataTable dt= new DataTable();
foreach (int id in lst)
{
dt.Merge(GetDataTableByID(id)); // Get Data Methode return DataTable
}
dtAll = dt;
This is what i did for merging two datatables and bind the final result to the gridview
DataTable dtTemp=new DataTable();
for (int k = 0; k < GridView2.Rows.Count; k++)
{
string roomno = GridView2.Rows[k].Cells[1].Text;
DataTable dtx = GetRoomDetails(chk, roomno, out msg);
if (dtx.Rows.Count > 0)
{
dtTemp.Merge(dtx);
dtTemp.AcceptChanges();
}
}
I am trying to add data to a newly created column...
DataSet ds = new DataSet;
ds.Tables[0].Columns.Add("Count");
Data.DataSource = ds;
Data.DataBind();
Where do I add, a hardcoded count? (I want count column to have '4')
You add data to rows - so:
DataSet ds = new DataSet();
DataTable table = ds.Tables.Add();
table.Columns.Add("Count", typeof(int));
table.Rows.Add(4);
However, there are probably easier options; a DataSet seems massively overkill to bind a single value.
It technically is a repeater function but if I get the hardcoded function... I can make the code to make it flexible. I got it to work. I was adding a column to an existing table. This is what I did...
for int i=0; i<ds.tables[0].Rows.Count; i++)
{
ds.tables[0].Rows[i]["Count"] = "4";
}