Greets! I am trying to create a DataRow and add it to an existing DataSet/DataTable. The problem I am running into is that the tables do not seem to be propagating correctly. I know the table exists yet it won't give me anything but null in return. Any ideas?
Code:
var TownDataSet = new DataSet("newDataSet");
var checkDataSet = new DataSet();
var checkDataTable = new DataTable();
var dataTableName = "someDataSet";
checkDataSet = TownDataSet.Clone();
checkDataTable = TownDataSet.Tables[dataTableName];
Console.WriteLine("STEP 4 " + checkDataSet.DataSetName);
Console.WriteLine("STEP 5 " + checkDataSet.Tables.Count);
Console.WriteLine("STEP 6 " + checkDataTable.TableName);
Error when I get to Step 6:
STEP 4 newDataSet
STEP 5 7
DataTableInsertTemp: System.NullReferenceException: Object reference not set to an instance of an object.
Let's analyze:
var TownDataSet = new DataSet("newDataSet");
var checkDataSet = new DataSet();
var checkDataTable = new DataTable();
var dataTableName = "someDataSet";
checkDataSet = TownDataSet.Clone();
checkDataTable = TownDataSet.Tables[dataTableName];
Where:
checkDataSet is a new DataSet containing 0 tables;
checkDataTable is a new DataTable contained in no DataSet
So:
TownDataSet.Tables is an empty collection
TownDataSet.Tables[dataTableName] is null
Try this instead:
var dataTableName = "someDataSet";
var TownDataSet = new DataSet("newDataSet");
var checkDataSet = new DataSet();
/* add a new DataTable to the DataSet.Tables collection */
checkDataSet.Tables.Add(new DataTable(dataTableName));
/* maybe you need to add some columns too */
checkDataSet.Tables[dataTableName].Columns.Add(new DataColumn("columnA", typeof(int)));
checkDataSet.Tables[dataTableName].Columns.Add(new DataColumn("columnB", typeof(string)));
/* create and initialize a new DataRow for the Tables[dataTableName] table */
var r = TownDataSet.Tables[dataTableName].NewRow();
r["columnA"] = 1;
r["columnB"] = "Some value";
/* add it to the Tables[dataTableName].Rows collection */
TownDataSet.Tables[dataTableName].Rows.Add(r);
EDIT
There are several ways to map a db into a dataset. I can suggest you a few:
POCO - Plain Old CLR Object. That is create an entity class for each table, mapping the table's fields into the class's properties.
Object-Relational Mapping. It is a framework layer that maps database tables into classes. A C# implementation is NHibernate.
ADO.NET Tables Schema. You can use the ADO.NET capabilities to import the database's tables schema definition into a dataset using the DataAdapter class.
Here a basic implementation:
DataSet ds = new DataSet();
ds.Tables.Add(new DataTable("myTable"));
da.FillSchema(ds.Tables["mytable"], SchemaType.Source);
var dataTableName = "someDataSet";
var TownDataSet = new DataSet("newDataSet");
var checkDataSet = new DataSet();
/* add a new DataTable to the DataSet.Tables collection */
checkDataSet.Tables.Add(new DataTable(dataTableName));
/*
* Fit the sql statement and the connection string depending on your scenario
* Set the *Command, *Connection and *DataAdapter actual provider
*/
SqlCommand cmd = new SqlCommand("select * from myTable");
SqlConnection conn = new SqlConnection("my connection string");
SqlDataAdapter da = new SqlDataAdapter();
cmd.Connection = conn;
da.SelectCommand = cmd;
/* that's it: the datatable is now mapped with the corresponding db table structure */
da.FillSchema(checkDataSet.Tables[dataTableName], SchemaType.Source);
Related
The following C# code runs a DAX statement and retrieves a DataTable. This works fine, but now I need to retrieve from the database up to N rows. Is there a way to limit the number of rows returned by the Fill function? If not, how can I retrieve the top N rows? Note that I need to keep this generic for any DAX statement, so you shouldn't change the DAX itself. Also, I don't want to retrieve all the data and then take the first N rows as the data may be too large.
public static DataTable runDaxStatement(int maxRows) {
var con = ConfigurationManager.ConnectionStrings["Default"].ConnectionString;
AdomdConnection conn = new AdomdConnection(con);
DataSet ds = new DataSet();
ds.EnforceConstraints = false;
AdomdCommand cmd = new AdomdCommand("evaluate customers", conn);
AdomdDataAdapter da = new AdomdDataAdapter(cmd);
da.Fill(ds);
return ds.Tables[0];
}
Came across the following TOPN function in the documentation.
This can be used to return the top N rows of the specified table.
For example
public static DataTable runDaxStatement(int maxRows) {
var connectionString = ConfigurationManager.ConnectionStrings["Default"].ConnectionString;
using(AdomdConnection connection = new AdomdConnection(connectionString)) {
string commandText = $"EVALUATE TOPN({maxRows}, customers, <orderBy_expression_here>)";
AdomdCommand command = connection.CreateCommand();
command.CommandText = commandText;
DataSet dataSet = new DataSet(){
EnforceConstraints = false
}
AdomdDataAdapter adapter = new AdomdDataAdapter(command);
adapter.Fill(dataSet);
return dataSet.Tables[0];
}
}
I would like to make one call (containing several SELECT statement) to the database and then databind the results to multiple components.
I'm using a DataSet and SqlDataAdapter to fill tables that are then bound to components.
Problem is the results of the first SELECT statement are put into both tables so I get a "'System.Data.DataRowView' does not contain a property..." error when I try to use the second lot of data on the second component.
Have I misunderstood how this is meant to work?
DataSet ds = new DataSet();
SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["myString"].ConnectionString);
StringBuilder topicDropDownListSQL = new StringBuilder();
topicDropDownListSQL.Append("SELECT topic.topic_ID, topic.topic_title FROM FPL2012_TOPIC as topic WHERE topic.topic_isEnabled = 1;");
topicDropDownListSQL.Append("SELECT explain.itemExplanationType_ID, explain.itemExplanationType_type FROM FPL2012_ITEM_EXPLANATION_TYPE as explain;");
SqlDataAdapter da = new SqlDataAdapter(topicDropDownListSQL.ToString(), connection);
ds.Tables.Add("Topics");
ds.Tables.Add("ExplainType");
ds.EnforceConstraints = false;
ds.Tables["Topics"].BeginLoadData();
da.Fill(ds.Tables[0]);
ds.Tables["Topics"].EndLoadData();
ds.Tables["ExplainType"].BeginLoadData();
da.Fill(ds.Tables[1]);
ds.Tables["ExplainType"].EndLoadData();
topicDropDownList.DataValueField = "topic_ID";
topicDropDownList.DataTextField = "topic_title";
topicDropDownList.DataSource = ds.Tables["Topics"];
topicDropDownList.DataBind();
explanationTypeDropDownList.DataValueField = "itemExplanationType_ID";
explanationTypeDropDownList.DataTextField = "itemExplanationType_type";
explanationTypeDropDownList.DataSource = ds.Tables["ExplainType"];
explanationTypeDropDownList.DataBind();
connection.Close();
You can use this acces the tables by there indexes not by there names
DataSet ds = new DataSet();
SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["myString"].ConnectionString);
String qry="SELECT topic_ID,topic_title FROM FPL2012_TOPIC WHERE topic_isEnabled = 1; SELECT itemExplanationType_ID, itemExplanationType_type FROM FPL2012_ITEM_EXPLANATION_TYPE ";
SqlDataAdapter da = new SqlDataAdapter(qry, connection);
da.Fill(ds)
topicDropDownList.DataValueField = "topic_ID";
topicDropDownList.DataTextField = "topic_title";
topicDropDownList.DataSource = ds.Tables[0];
topicDropDownList.DataBind();
explanationTypeDropDownList.DataValueField = "itemExplanationType_ID";
explanationTypeDropDownList.DataTextField = "itemExplanationType_type";
explanationTypeDropDownList.DataSource = ds.Tables[1];
explanationTypeDropDownList.DataBind();
connection.Close();
OK, I tried using a datareader next, didn't expect it to work but it does! I can make multiple select statements and then fill multiple componenets. I'm not marking this as an answer as I still think it would be useful to know how to do it using the dataset.
The new code that worked for me (in case it is useful):
string connectionString = WebConfigurationManager.ConnectionStrings["myString"].ConnectionString;
SqlConnection connection = new SqlConnection(connectionString);
StringBuilder sql = new StringBuilder();
sql.Append("SELECT topic.topic_ID, topic.topic_title FROM FPL2012_TOPIC as topic WHERE topic.topic_isEnabled = 1;");
sql.Append("SELECT explain.itemExplanationType_ID, explain.itemExplanationType_type FROM FPL2012_ITEM_EXPLANATION_TYPE as explain;");
SqlCommand command = new SqlCommand(sql.ToString(), connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
topicDropDownList.DataSource = reader;
topicDropDownList.DataValueField = "topic_ID";
topicDropDownList.DataTextField = "topic_title";
topicDropDownList.DataBind();
reader.NextResult();
explanationTypeDropDownList.DataSource = reader;
explanationTypeDropDownList.DataValueField = "itemExplanationType_ID";
explanationTypeDropDownList.DataTextField = "itemExplanationType_type";
explanationTypeDropDownList.DataBind();
reader.Close();
connection.Close();
How can I add data from a DataTable to a database table directly?
I have searched on the internet not being able to get information from any site.
I have a DataTable and now I want to add that data to a database table.
importData.Tables[1];
for(int r = 0; r< totalrecoreds; r++;)
{
Array test[] = importData.Tables[1].Rows[r].ItemArray.ToArray;
}
What can I do? Do I have to add data one by one using for loop or is there any other method?
Provided that the schema of the DataTable is the same as the schema of the database table you can just use a DataAdapter to insert the data.
using(var connection = new SqlConnection(...))
using(var adapter = new SqlDataAdapter("SELECT * FROM TABLENAME", connection))
using(var builder = new SqlCommandBuilder(adapter))
{
adapter.UpdateCommand = builder.GetUpdateCommand();
adapter.InsertCommand = builder.GetInsertCommand();
adapter.DeleteCommand = builder.GetDeleteCommand();
adapter.Update(importData.Tables[1]);
}
If the schemas differ you have to add mappings to the DataAdapter, like the MSDN DataAdapter example illustrates.
Using FillSchema-method of the data adapter I obtain the table structure
using (SqlConnection sqlConn = new SqlConnection(connectionString))
{
var dataAdapter = new SqlDataAdapter();
var dataSet = new DataSet();
sqlConn.Open();
string sqlSelectCommand = "select * from Projects;\nselect * from Staff"
dataAdapter.SelectCommand = new SqlCommand(sqlSelectCommand, sqlConn);
dataAdapter.FillSchema(dataSet, SchemaType.Source);
dataAdapter.Fill(dataSet);
dataSet.Tables[0].TableName = "Projects";
dataSet.Tables[1].TableName = "Staff";
// create relations between the tables
// is there an alternative way?
var relation = new DataRelation("FK_Projects_Staff", dataSet.Tables["Staff"].Columns["ID"], dataSet.Tables["Projects"].Columns["Responsible_ID"], true);
dataSet.Relations.Add(relation);
// do some manipulations on data using projectsDataAdapter and staffDataAdapter
// ...
}
Is there a similar way to fill the relations of all relevant tables?
Please see if the below link can help you.
http://csharptutorial.com/how-to-create-a-dataset-programmatically/
OleDbConnection _connection = new OleDbConnection();
StringBuilder ConnectionString = new StringBuilder("");
ConnectionString.Append(#"Provider=Microsoft.Jet.OLEDB.4.0;");
ConnectionString.Append(#"Extended Properties=Paradox 5.x;");
ConnectionString.Append(#"Data Source=C:\Clients\Rail\Wheelsets;");
_connection.ConnectionString = ConnectionString.ToString();
_connection.Open();
OleDbDataAdapter da = new OleDbDataAdapter("SELECT * FROM Vehicles;", _connection);
DataSet dsRetrievedData = new DataSet();
da.Fill(dsRetrievedData);
OleDbCommandBuilder builder = new OleDbCommandBuilder(da);
da.InsertCommand = builder.GetInsertCommand();
////Insert new row
DataRow rowNew = dsRetrievedData.Tables[0].NewRow();
rowNew[dsRetrievedData.Tables[0].Columns[0].ColumnName] = "978";
rowNew[dsRetrievedData.Tables[0].Columns[1].ColumnName] = "222";
rowNew[dsRetrievedData.Tables[0].Columns[4].ColumnName] = "999";
rowNew[dsRetrievedData.Tables[0].Columns[5].ColumnName] = "999";
rowNew[dsRetrievedData.Tables[0].Columns[6].ColumnName] = "999";
dsRetrievedData.Tables[0].Rows.Add(rowNew);
dsRetrievedData.Tables[0].AcceptChanges();
dsRetrievedData.AcceptChanges();
int result = da.Update(dsRetrievedData);
thats the code i use. as you can see i have a paradox table. and some how result = 0 at end of it all.
any ideas what is my mistake?
thanks upfront.
-=Noam=-
What is your InsertCommand?
Also try after removing these line
dsRetrievedData.Tables[0].AcceptChanges();
dsRetrievedData.AcceptChanges();
if you call AcceptChanges all changes in the datatable is accepted so there is no rows which is changed so there is nothing to update
Remove call to AcceptChanges() :
dsRetrievedData.Tables[0].AcceptChanges();
dsRetrievedData.AcceptChanges();
According to MSDN:
Commits all the changes made to this
DataSet since it was loaded or since
the last time AcceptChanges was
called.
Which means, it marks newly added row as not new.