I have two questions:
Can we assign objectdatasource control to a dataset?
Can we return two or more tables using object data source control to gridview or detailsview.
My main focus is I have to store the object data source in the dataset otherwise my application will need to be changed by a lot.
1 Yes you can assign objectdatasource to a DataSet
private DataSet GetDataSet(ObjectDataSource ods)
{
var ds = new DataSet();
var dv = (DataView)ods.Select();
if (dv != null && dv.Count > 0)
{
var dt = dv.ToTable();
ds.Tables.Add(dt);
}
return ds;
}
2 yes you can return lot of tables, but when you bind you specify your index table.
GridView1.DataSource = YourDataSet.Tables[0];
GridView2.DataSource = YourDataSet.Tables[2];
An 'ObjectDataSource' has no data.
He simply returns the result of a method, this method should return an IEnumerable. The IEnumerable can be of POCO's, String's, Int32's, etc..
how to store a objectdatasource controls data into a dataset
It would be possible if you return a "System.Data.DataTable" and then, yes, in this case you could store it in a "System.Data.DataSet". But for me, it makes little sense.
private void Form5_Load(object sender, EventArgs e)
{
// Creating and configuring the ObjectDataSource component:
var objectDataSource = new Telerik.Reporting.ObjectDataSource();
objectDataSource.DataSource = GetAllData(); // GetData returns a DataSet with three tables
objectDataSource.DataMember = "Product"; /// Indicating the exact table to bind to. If the DataMember is not specified the first data table will be used.
objectDataSource.CalculatedFields.Add(new Telerik.Reporting.CalculatedField("FullName", typeof(string), "=Fields.Name + ' ' + Fields.ProductNumber")); // Adding a sample calculated field.
// Creating a new report
Telerik.Reporting.Report report = new Telerik.Reporting.Report();
// Assigning the ObjectDataSource component to the DataSource property of the report.
report.DataSource = objectDataSource;
// Use the InstanceReportSource to pass the report to the viewer for displaying
Telerik.Reporting.InstanceReportSource reportSource = new Telerik.Reporting.InstanceReportSource();
reportSource.ReportDocument = report;
// Assigning the report to the report viewer.
reportViewer1.ReportSource = reportSource;
// Calling the RefreshReport method (only in WinForms applications).
reportViewer1.RefreshReport();
}
static DataSet GetAllData()
{
const string connectionString =
"Data Source=(local)\\SQLEXPRESS;Initial Catalog=AdventureWorks;Integrated Security=True";
string selectCommandText = "SELECT Name, ProductCategoryID FROM Production.ProductCategory;" +
"SELECT Name, ProductCategoryID FROM Production.ProductSubcategory;" +
"SELECT Name, ProductNumber FROM Production.Product;";
SqlDataAdapter adapter = new SqlDataAdapter(selectCommandText, connectionString);
DataSet dataSet = new DataSet();
// The data set will be filled with three tables: ProductCategory, ProductSubcategory
// and Product as the select command contains three SELECT statements.
adapter.Fill(dataSet);
// Giving meaningful names for the tables so that we can use them later.
dataSet.Tables[0].TableName = "ProductCategory";
dataSet.Tables[1].TableName = "ProductSubcategory";
dataSet.Tables[2].TableName = "Product";
return dataSet;
}
Related
I have wrote an application which is connected to an SQL server. There is a function which list out one of the table's rows in a DataGridView. This DataGridView is bound to a BindingSource which is connected to the table directly via a DataSet. It has been clicked via GUI.
My problem is, when something changes in the table, the DataSource is not refreshing. Not even I edit something via my application or just delete a row it still stands there even if the SQL table does not contains anymore.
I have wrote a refresh procedure which have been called every time I click on the table view menu or use the refresh button, it looks like that:
public void SrvMgmtRefresh()
{
string select = "select * from ServersInput";
srvMgmtDataGridView.DataSource = null;
SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(select, con);
DataSet DS = new DataSet();
sqlDataAdapter.Fill(DS, "ServersInput");
srvMgmtDataGridView.DataSource = DS.Tables[0];
}
Does anyone have any idea what I have did wrong? I see in the application that it reload the content of the table but it still not refresh.
Thanks in advance.
Try this :
DataSet ds = new DataSet();
using (SqlDataAdapter sda = new SqlDataAdapter("ProcedureName", _context.Database.GetConnectionString()))
{
sda.SelectCommand.CommandType = CommandType.StoredProcedure;
sda.SelectCommand.Parameters.Add(new
SqlParameter("#isMedicationPerscriber", SqlDbType.Bit)).Value =
filteringParams.IsMedicationPerscriber;
sda.SelectCommand.Parameters.Add(new
SqlParameter("#isInpersonSession", SqlDbType.Bit)).Value =
filteringParams.InpersonSession;
sda.Fill(ds);
}
int totalRecords = Convert.ToInt32(ds.Tables[1].Rows[0][0]);
var items = ds.Tables[0].AsEnumerable()
.Select(dataRow => new User
{
ZipCode = dataRow.Field<string>("ZipCode"),
IsDeleted = dataRow.Field<bool>("IsDeleted"),
IsConnected = dataRow.Field<bool>("IsConnected"),
Latitude = dataRow.Field<double?>("Latitude"),
Longitude = dataRow.Field<double?>("Longitude"),
}).Where(x => x.UserId != Guid.Parse(filteringParams.UserId)).ToList();
This code below works for me, but i have not been able to insert ---Select--- to the for first index with value zero, i have tried:
cboGrade.Items.Insert(0,"---Select---)
but it is not working for me.
Also i want to able to retrieve and display the displaymember and displayvalue on the combo box while retrieving from database without items not being repeated:
private void LoadGrade()
{
using (SQLiteConnection conn = new SQLiteConnection(connstring))
{
try
{
string query = "select GradeCode, GradeName from Grade";
SQLiteDataAdapter da = new SQLiteDataAdapter(query, conn);
conn.Open();
DataSet ds = new DataSet();
da.Fill(ds, "OrgGrade");
cboGrade.DisplayMember = "GradeName";
cboGrade.ValueMember = "GradeCode";
cboGrade.DataSource = ds.Tables["OrgGrade"];
}
catch (Exception ex)
{
MessageBox.Show("Error occured loading grade!");
}
}
}
Items only works if you have an unbound combo hence you either need to build the items array OR use binding.
What you need to do is insert into the DataTable you are binding like this:
DataTable dt = ds.Tables["OrgGrade"]
// generate the data you want to insert
DataRow newRow= dt.NewRow();
newRow.GradeName = "-- Select --";
newRow.GradeCode = 0;
// insert in the desired place
dt.Rows.InsertAt(newRow, 0);
Then bind using:
cboGrade.DataSource = dt;
Similar to what you have.
I am trying to query or match user input against a dataset using a DataTable:
I am populating the dataset from a stored procedure which selects only a single column from a single table: Example: UserID Column. **I am not selecting the entire content of the table.*
public static DataSet LoadProfile()
{
SqlCommand cmdSQL = new SqlCommand("usp_LoadProfile", ConnectDatabase);
cmdSQL.CommandType = CommandType.StoredProcedure;
SqlDataAdapter daSQL = new SqlDataAdapter(cmdSQL);
DataSet ds = new DataSet();
daSQL.Fill(ds);
try
{
ConnectDatabase.Open();
cmdSQL.ExecuteNonQuery();
}
catch(Exception)
{
StatusMsg = ex.Message;
}
finally
{
ConnectDatabase.Close();
cmdSQL.Parameters.Clear();
cmdSQL.Dispose();
}
return ds;
}
I have the following method called in the form load event: I need to populate the dataset on from load.
public static DataTable LoadData()
{
DataSet dsView = new DataSet();
dsView = LoadProfile();
DataTable tblExample = dsView.Tables["Example"];
return tblExample;
}
Finally what I would like to do is match the user entry from the DataTable.
I have this in button event:
DataRow[] results;
results = LoadData().Select(txtExample.Text);
Beyond this point, I could use a for loop but there is only one record for each person.
I am trying to match the user entry with the dataset via the datatable.
The last line should be
DataRow[] results;
results = LoadData().Select("UserID = '" + txtExample.Text +"'");
Supposing that UserID is a field of text type. If instead is of numeric type then remove the quotes
results = LoadData().Select("UserID = " + txtExample.Text);
However I should point that the code in LoadProfile following the daSQL.Fill(ds); call is not needed and you can remove it (just return the DataSet though)
Use the following simple query on dataset:
DataRow[] dRow = dataSetName.Tables[0].Select("fieldToMatch = '" + userInput.ToString() + "' ");
I have Stored Procedure which returns Multiple tables as ResultSet. I Stored it in DataTable and Pass that DataTable Object to Another Form Which Print Tables In MY Web Page.
My Question is How Can i Stored Multiple ResultSet Returned from Stored Procedure into SINGLE DataTable Object Which I Can return to another function.
public static DataTable[] getGraphData(Int32 type)
{
SqlConnection oConn = null;
DataSet dsReturn = null;
DataTable[] dtReturn=new DataTable[2];
try
{
getConnection(ref oConn, 1);
using (SqlStoredProcedure sspObj = new SqlStoredProcedure("dbo.usp_getGraphData", oConn, CommandType.StoredProcedure))
{
sspObj.AddParameterWithValue("#Type", SqlDbType.Int, 0, ParameterDirection.Input, type);
dsReturn = sspObj.ExecuteDataSet();
dtReturn[0] = dsReturn.Tables[0];
dtReturn[1] = dsReturn.Tables[1];
dtReturn[2] = dsReturn.Tables[2];
sspObj.Dispose();
}
closeConnection(ref oConn);
}
catch (Exception xObj)
{
//dtReturn[] = new DataTable();
}
return dtReturn;
}
Function Which Takes the all three DataTables
DataTable dtOutput = Generix.getGraphData(type);
How to get Each DataTable From Here ? Means 0th Element to dtOutput1 , 1st Element to dtOutput2.....Like wise
Why don't you use a dataset as podiluska mentioned, and then access the DataSet.Tables property to gets your three table one by one.
If the three table structure is difderent does not make sense to foece them into a table. For this the DataSet is the better way. It is kind of collection of your table.
EDIT for the question about the DataTable[]:
DataTable[] dtOutputs = Generix.getGraphData(type);
//dtReturn[0]
DataTable dtOutput0 = dtOutputs[0];
//dtReturn[1]
DataTable dtOutput1 = dtOutputs[1];
//dtReturn[2]
DataTable dtOutput2 = dtOutputs[2];
Or if you need not only reference those table, but copy them, you can use .Copy() like:
//dtReturn[0]
DataTable dtOutput1 = dtOutputs[1].Copy;
I still think that the best way would be returning a DataSet by the query (it doesn't make sense to make a DataTable query from that.)
public static DataSet getGraphData(Int32 type)
{
SqlConnection oConn = null;
DataSet dsReturn = null;
try
{
getConnection(ref oConn, 1);
using (SqlStoredProcedure sspObj = new SqlStoredProcedure("dbo.usp_getGraphData", oConn, CommandType.StoredProcedure))
{
sspObj.AddParameterWithValue("#Type", SqlDbType.Int, 0, ParameterDirection.Input, type);
dsReturn = sspObj.ExecuteDataSet();
//You don't need Dispose() - because the using will do that on sspObj
}
closeConnection(ref oConn);
}
catch (Exception xObj)
{
dsReturn = new DataSet("Empty");
}
return dsReturn ;
}
And calling the method like this:
DataSet dsOutput = Generix.getGraphData(type);
//Simply a reference or Copy() the DataSet's tables:
DataTable dtOutput0 = dsOutput.Tables[0];
DataTable dtOutput1 = dsOutput.Tables[1];
DataTable dtOutput2 = dsOutput.Tables[2];
Use a union in your stored procedure to join the result sets together
ie:
SELECT * from yourtable WHERE name='bob'
UNION ALL
SELECT * from yourtable WHERE name='jane'
If you want to return your multiple tables into a single object, you can use a DataSet (which contains multiple tables) instead of a DataTable. You populate it in the same way.
eg:
DataSet dst = new DataSet();
new SqlAdapter(command).Fill (dst);
I want to show a master / detail relationship using two datagridviews and DataRelation in C#.
The relation between the master and the detail table is an ID from type string (and there is no chance to change the ID to type integer).
It seems like the DataGridView is not able to update the detail view when changing the row in the master table.
Does anybody know if it is possible to achieve a master / detail view using a string ID and if yes, how? Or do I have to use an external DataGrid from another company?
UPDATE
Personally I don't see a difference in using a string instead of an integer. The only thing I can think of is that the grid cannot handle a master detail view using a string ID relation.
Here is an example, please create a new VS 2008 project and copy the code. Change the connection string and the datarelation:
using System;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;
public class Form1 : System.Windows.Forms.Form
{
private DataGridView masterDataGridView = new DataGridView();
private BindingSource masterBindingSource = new BindingSource();
private DataGridView detailsDataGridView = new DataGridView();
private BindingSource detailsBindingSource = new BindingSource();
[STAThreadAttribute()]
public static void Main()
{
Application.Run(new Form1());
}
// Initializes the form.
public Form1()
{
masterDataGridView.Dock = DockStyle.Fill;
detailsDataGridView.Dock = DockStyle.Fill;
SplitContainer splitContainer1 = new SplitContainer();
splitContainer1.Dock = DockStyle.Fill;
splitContainer1.Orientation = Orientation.Horizontal;
splitContainer1.Panel1.Controls.Add(masterDataGridView);
splitContainer1.Panel2.Controls.Add(detailsDataGridView);
this.Controls.Add(splitContainer1);
this.Load += new System.EventHandler(Form1_Load);
this.Text = "DataGridView master/detail demo";
}
private void Form1_Load(object sender, System.EventArgs e)
{
// Bind the DataGridView controls to the BindingSource
// components and load the data from the database.
masterDataGridView.DataSource = masterBindingSource;
detailsDataGridView.DataSource = detailsBindingSource;
GetData();
// Resize the master DataGridView columns to fit the newly loaded data.
masterDataGridView.AutoResizeColumns();
// Configure the details DataGridView so that its columns automatically
// adjust their widths when the data changes.
detailsDataGridView.AutoSizeColumnsMode =
DataGridViewAutoSizeColumnsMode.AllCells;
}
private void GetData()
{
try
{
// Specify a connection string. Replace the given value with a
// valid connection string for a Northwind SQL Server sample
// database accessible to your system.
String connectionString =
"";
SqlConnection connection = new SqlConnection(connectionString);
WindowsFormsApplication1.ConcordanceServer.IConcordanceServerToGUI cs = new WindowsFormsApplication1.ConcordanceServer.ConcordanceServerToGUIClient();
// Create a DataSet.
DataSet data = new DataSet();
data.Locale = System.Globalization.CultureInfo.InvariantCulture;
// Add data from the Customers table to the DataSet.
SqlDataAdapter masterDataAdapter = new
SqlDataAdapter("select * from customers", connection);
masterDataAdapter.Fill(data, "Customers");
// Add data from the Orders table to the DataSet.
SqlDataAdapter detailsDataAdapter = new
SqlDataAdapter("select * from Orders", connection);
detailsDataAdapter.Fill(data, "Orders");
// Establish a relationship between the two tables.
DataRelation relation = new DataRelation("CustomersOrders",
data.Tables["Customers"].Columns["strID"],
data.Tables["Orders"].Columns["strID"]);
data.Relations.Add(relation);
// Bind the master data connector to the Customers table.
masterBindingSource.DataSource = data;
masterBindingSource.DataMember = "Customers";
// Bind the details data connector to the master data connector,
// using the DataRelation name to filter the information in the
// details table based on the current row in the master table.
detailsBindingSource.DataSource = masterBindingSource;
detailsBindingSource.DataMember = "CustomersOrders";
}
catch (SqlException)
{
MessageBox.Show("To run this example, replace the value of the " +
"connectionString variable with a connection string that is " +
"valid for your system.");
}
}
}