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();
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 really appreciate a help in this code. I have a DataSet with two tables; I need to create a relation based on two columns as primary key:
public DataSet GetAll()
{
string sql = $#"SELECT * FROM Journal ORDER BY JvNO, cYear;
SELECT * FROM JournalDetail ORDER BY JvNO, cYear";
using (SqlConnection connection = new SqlConnection(GlobalConfig.ConnString()))
{
connection.Open();
SqlCommand cmd = new SqlCommand(sql, connection);
SqlDataAdapter da = new SqlDataAdapter(sql, connection);
DataSet ds = new DataSet();
da.Fill(ds);
ds.Relations.Add("Journal_Batch", new DataColumn[] { ds.Tables[0].Columns["JvNO"], ds.Tables[0].Columns["cYear"] },
new DataColumn[] { ds.Tables[1].Columns["JvNO"], ds.Tables[1].Columns["cYear"] });
return ds;
}
}
Currently, I'm doing it like this and it's working but I need it with DataSet relation:
public DataSet GetJournalByID(int JVNO, int cYear)
{
string sql = $#"SELECT * FROM Journal WHERE JvNO = { JVNO } and cYear = { cYear };
SELECT * FROM JournalDetail WHERE JvNO = { JVNO } and cYear = { cYear };";
using (SqlConnection connection = new SqlConnection(GlobalConfig.ConnString()))
{
connection.Open();
SqlCommand cmd = new SqlCommand(sql, connection);
SqlDataAdapter da = new SqlDataAdapter(sql, connection);
DataSet ds = new DataSet();
da.Fill(ds);
return ds;
}
}
I don't know what's wrong with first code, as it returns all matching JvNO or Year.
i want to use the first one to fill two grids as follow:
private void GetData()
{
DataSet currentDs = new DataSet();
grdJournalDetails.DataSource = null;
grdJournal.DataSource = null;
JournalConnector journalConnection = new JournalConnector();
currentDs = journalConnection.GetAll();
grdJournal.DataSource = currentDs.Tables[0];
grdJournalDetails.DataSource = currentDs.Tables[1];
}
then with each row selected from grdJournal to display grdJournalDetails with related data without calling each time the second snippet of code.
i used Dapper and i'm familiar with it, but with devexpress grid, it have to be a datatable to use the event gvJournal_FocusedRowChanged, otherwise datarow returns always null;
Thanks for any suggestion.
i have a form with a collection of about five drop down . i have my query as follows .
string sql = "SELECT a.clientID ,a.[cname],b.bid,b.[bname],c.contactID, c.[name] FROM "
+ " dbo.[CLIENT] AS a INNER JOIN dbo.[BRANCH] AS b "
+ "ON a.clientID = b.clientID JOIN dbo.[CONTACT] AS "
+ " c ON b.bid = c.bid ORDER BY a.clientID ";
i then followed and bind my drop down individually to their respective columns as follows.
SqlCommand cmd = new SqlCommand(sql, connection);
cmd.CommandType = CommandType.Text;
SqlDataReader reader = cmd.ExecuteReader();
drClient.Enabled = true;
drClient.DataSource = reader;
drClient.DataTextField = "cname";
drClient.DataValueField = "clientID";
drClient.DataBind();
drBranch.Enabled = true;
drBranch.DataSource = reader;
drBranch.DataTextField = "bname";
drBranch.DataValueField = "bid";
drBranch.DataBind();
drContact.Enabled = true;
drContact.DataSource = reader;
drContact.DataTextField = "name";
drContact.DataValueField = "contactID";
drContact.DataBind();
drEmail.Enabled = true;
drEmail.DataSource = reader;
drEmail.DataTextField = "name";
drEmail.DataValueField = "contactID";
drEmail.DataBind();
drFax.Enabled = true;
drFax.DataSource = reader;
drFax.DataValueField = "contactID";
drFax.DataTextField = "name";
drFax.DataBind();
when i run this, only the first drop down bind successfully. The rest don't. I also try to loop through the reader by adding
while(reader.read())
{
then my bindings
}
the above also fails. I though of looping as below as well.
while(read.HasRows)
{
}
it still fails. I am confused,any help would be appreciated. thanks
Reader is readonly and forward only that's why only first dropdonw get filled with data and others are empty.
You can use datset or Datatable for same problem .
SqlCommand cmd = new SqlCommand(sql, connection);
cmd.CommandType = CommandType.Text;
Dataset dsresult = cmd.ExecuteDataset();
If(dsResult !=null)
{
if(dsResult.Rows.count>0)
{
drClient.Enabled = true;
drClient.DataSource = dsResult.Tables[0] ;
drClient.DataTextField = Convert.ToString(ds.Tables[0].Columns["cname"]);
drClient.DataValueField = ds.Tables[0].Columns["clientID"] ;
drClient.DataBind();
}
}
Datareader is connected architecture needs continuous connection and fetches one row at a time in forward mode better use dataset which uses disconnected architecture and can be used for retrieving data multiple times.
This seems clear postback problem.
Bind your drop down on !postback.
Eg.
if(!IsPostBack)
{
populateDdl();
}
Either you will have to make a seperate reader for each binding
or you can do this by filling a datatable ( i would prefer this). Like,
DataTable dt = new DataTable();
using (SqlDataAdapter a = new SqlDataAdapter(sql, connection))
{
a.Fill(dt);
}
drClient.DataSource = dt;
drClient.DataBind();
drBranch.DataSource = dt;
drBranch.DataBind();
drContact.DataSource = dt;
drContact.DataBind();
drFax.DataSource = dt;
drFax.DataBind();
Your choices are to either rerun/refill it or create separate readers or better yet fill a datatable instead and then you can reuse the datatable.
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.