How to use variables in all the windows forms? - c#

In my c# project i used many forms and my database is in sql server 2008.
I create one app.config file in that my connection string.
<add name="Courier_Management_System" connectionString="Data Source=.\sqlexpress;Initial Catalog=Courier_Management_System;Integrated Security=True" />
now in all the forms i write the following lines for working with database
SqlConnection cnn = new SqlConnection();
cnn.ConnectionString = ConfigurationManager.ConnectionStrings["Courier_Management_System"].ToString();
SqlDataAdapter adp = new SqlDataAdapter();
DataSet ds = new DataSet();
DataTable dt = new DataTable();
so my question is if it is possible to write the above all the lines once and use it in all the forms.

Create a class lets say MyDatabase and in its constructor put your code as above and make these variables public. Now you can create object of this class and use these variables, as these will be initialized as soon as you create the object.
Example code:
class MyDatabase
{
SqlConnection cnn;
SqlDataAdapter adp;
DataSet ds;
DataTable dt;
public MyDatabase()
{
cnn = new SqlConnection();
cnn.ConnectionString = ConfigurationManager.ConnectionStrings["Courier_Management_System"].ToString();
adp = new SqlDataAdapter();
ds = new DataSet();
dt = new DataTable();
}
}
Using this class
class YourForm
{
void someMethod()
{
MyDatabase myDatabase = new MyDatabase();
myDatabase.ds = //do something..
gridView.DataSource = myDatabase.ds; //using the variable..
}
}

The right way to do these things is to have a separate project that does the data access. But the most important idea is that you want the data access to take place in one location, e.g. in a class file like Praveen demonstrated. You can even add extra functions to execute queries and return specific resultsets, e.g.:
class MyDatabase
{
SqlConnection cnn;
SqlDataAdapter adp;
DataSet ds;
DataTable dt;
public MyDatabase()
{
cnn = new SqlConnection();
cnn.ConnectionString = ConfigurationManager.ConnectionStrings["Courier_Management_System"].ToString();
adp = new SqlDataAdapter();
ds = new DataSet();
dt = new DataTable();
}
public Dataset ExecuteQuery(string SQL)
{
cnn.Open();
var ret = cnn.Execute(SQL);
cnn.Close();
return ret;
}
}

Create a static method in your Program.cs class
Public Static SqlConnection GetConnection()
{
SqlConnection cnn = new SqlConnection();
cnn.ConnectionString = configurationManager.ConnectionStrings["Courier_Management_System"].ToString();
return cnn;
}
you can call this method as Program.GetConnection() where ever you want a connection object, You only need to change the connection string in only one place if there is any change.
No need to add
SqlDataAdapter adp = new SqlDataAdapter();
DataSet ds = new DataSet();
DataTable dt = new DataTable();
inside that method , because in most of the time you are not suppose to use those variables .

Related

C# The SelectCommand property has not been initialized before calling 'Fill'. in WinForm

I'm trying to programmatically populate DataGridView in my Windows Form with DB data, but I'm obviously doing something wrong.
namespace UDDKT
{
public partial class Form2 : Form
{
SqlConnection connection;
string connectionString;
DataSet ds = new DataSet();
SqlDataAdapter DaDavaoci = new SqlDataAdapter();
SqlDataAdapter DaAkcije = new SqlDataAdapter();
public Form2()
{
InitializeComponent();
connectionString = ConfigurationManager.ConnectionStrings["UDDKT.Properties.Settings.UDDKTConnectionString"].ConnectionString;
}
public SqlCommand SlctDavaoci { get; private set; }
private void Form2_Load(object sender, EventArgs e)
{
PopuniDgDavaoci();
}
private void PopuniDgDavaoci()
{
using (connection = new SqlConnection(connectionString))
using (SqlDataAdapter adapter = new SqlDataAdapter("SELECT * FROM Davaoci", connection))
{
DaDavaoci.SelectCommand = SlctDavaoci;
DaDavaoci.Fill(ds, "TblDavaoci");
}
}
}
}
When I try to run it, it highlights DaDavaoci and says: Exception Unhandled System.InvalidOperationException: 'The SelectCommand property has not been initialized before calling 'Fill'.'
You are using the wrong SqlAdapter.
At the top you create an adapter named DaDavoci:
SqlDataAdapter DaDavaoci = new SqlDataAdapter();
But you are passing no CommandText and no Connection.
At the bottom you create a new adapter named adapter (with connection and commandtext). But then you are using the adapter from the top again which still has no commandtext and no connection.
using (connection = new SqlConnection(connectionString))
using (SqlDataAdapter adapter = new SqlDataAdapter("SELECT * FROM Davaoci", connection))
{
DaDavaoci.SelectCommand = SlctDavaoci;
DaDavaoci.Fill(ds, "TblDavaoci");
}
You should use the adapter you have created which contains a commandtext and a connection like this
using (SqlDataAdapter adapter = new SqlDataAdapter("SELECT * FROM Davaoci", connection))
{
adapter.SelectCommand = SlctDavaoci;
adapter.Fill(ds, "TblDavaoci");
}
I don't know exactly what you are trying to do, but i think the initialization of the two adapters on the top of your code dont make sense (at least to me). I would not store the connection nor the adapter in a classvariable, but instead create new ones when you need them. (If you are using the using-keyword, the instace you create is gonna be disposed after the end of the using-scope. So either use using and create new instances where you need them or make it a classvariable and not use using)
Try modifying this section of code to something like this:
string queryString = "SELECT * FROM Davaoci";
private DataSet PopuniDgDavaoci(DataSet ds, string connectionString, string queryString)
{
using (connection = new SqlConnection(connectionString))
{
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand(queryString, connection);
adapter.Fill(ds);
}
return ds;
}
Then you can attach your dataset to your grid.
Something like:
MyGrid.DataSource = ds;
More info here: https://learn.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqldataadapter?view=netframework-4.8
It should be corrected because there is nothing in sql command
using (connection = new SqlConnection(connectionString))
{
using (SqlDataAdapter adapter = new SqlDataAdapter("SELECT * FROM Davaoci",connection ))
{
SqlCommandBuilder commandBuilder = new SqlCommandBuilder(adapter);
DataTable table = new DataTable
{
Locale = CultureInfo.InvariantCulture
};
dataAdapter.Fill(table);
YourDataGridView.DataSource = table;
}
}
For example please go through this
How to: Bind data to the Windows Forms DataGridView control
Here is what I did to solve my issue:
namespace UDDKT
{
public partial class Form2 : Form
{
DataSet ds = new DataSet();
SqlDataAdapter DaDavaoci = new SqlDataAdapter();
SqlDataAdapter DaAkcije = new SqlDataAdapter();
SqlConnection cs = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\UDDKT.mdf;Integrated Security=True");
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
SqlCommand SlctDavaoci = new SqlCommand("SELECT * FROM Davaoci", cs);
DaDavaoci.SelectCommand = SlctDavaoci;
DaDavaoci.Fill(ds, "TblDavaoci");
SqlCommand SlctAkcije = new SqlCommand("SELECT * FROM AkcijaDDK", cs);
DaAkcije.SelectCommand = SlctAkcije;
DaAkcije.Fill(ds, "TblAkcije");
DgDavaoci.DataSource = ds.Tables["TblDavaoci"];
DgAkcije.DataSource = ds.Tables["TblAkcije"];
}
}
}

SqlDataAdapter Close connection method

I have a code like this in my program and I believe that it's not closing the connection after that the data is getting filled in.
public static string ConnectionInfo = System.Configuration.ConfigurationManager.ConnectionStrings["Default"].ConnectionString;
public static DataTable ExecuteQuery(string query, string table)
{
SqlConnection cnn = new SqlConnection(ConnectionInfo);
SqlDataAdapter Adp = new SqlDataAdapter(query, cnn);
DataSet Ds = new DataSet();
Adp.Fill(Ds, table);
return Ds.Tables[table];
}
Is there any problem in this code ?
The only problem is that you are not using the using statement for the SqlConnection and the DataAdapter. However, DbDataAdapter.Fill opens and closes the connection implicitely.
public static DataTable ExecuteQuery(string query, string table)
{
using(SqlConnection cnn = new SqlConnection(ConnectionInfo))
using(SqlDataAdapter Adp = new SqlDataAdapter(query, cnn))
{
DataTable tbl = new DataTable();
Adp.Fill(tbl);
return tbl;
}
}
The connection object associated with the SELECT statement must be
valid, but it does not need to be open. If the connection is closed
before Fill is called, it is opened to retrieve data, then closed. If
the connection is open before Fill is called, it remains open.
Note that
the using statement will close the connection implicitely even on error
i have used DataAdapter.Fill(DataTable) because you're using a single table anyway
Edit: i've only just noticed that you are using a parameter for the table-name. You can also use DbDataAdapter.Fill(DataSet, String) instead. That does not change anything.
Add a using statement in order to close the connection reliably. This ensures that the connection is closed even if an exception occurs. Change your code as follows:
public static DataTable ExecuteQuery(string query, string table)
{
using(SqlConnection cnn = new SqlConnection(ConnectionInfo))
{
SqlDataAdapter Adp = new SqlDataAdapter(query, cnn);
DataSet Ds = new DataSet();
Adp.Fill(Ds, table);
return Ds.Tables[table];
}
}
Whatever the opening/closing of the connections should be done in try-catch-finally block.
And we should not be using "using"
[using (SqlConnection connection = new SqlConnection(connectionString))]
block. Because if something goes wrong with the network or any exception cause. Connection is not closed. So better to be use try-catch block.
public static DataTable ExecuteQuery(string query, string table)
{
DataSet Ds = new DataSet();
SqlConnection cnn = new SqlConnection(ConnectionInfo);
try{
SqlDataAdapter Adp = new SqlDataAdapter(query, cnn);
Adp.Fill(Ds, table);
return Ds.Tables[table];
}
catch{
throw;
}
finally{
cnn.Close();
}
}

Creating Dataset Dynamically and passing to ReportViewer

all i did is just create a reportViewer in the form, then i have this code:
SqlConnection cn = new SqlConnection(#"Data Source=.\SQLEXPRESS;AttachDbFilename=G:\I.S\C#\billingSystem\Store.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True");
private void Form1_Load()
{
runRptViewer();
cn.Open();
}
private void rptGetDataset()
{
DataSet ds = new DataSet();
ds.DataSetName = "dsNewDataSet";
SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM NewBill", cn);
ds.GetXmlSchema();
da.Fill(ds);
ds.WriteXmlSchema(#"G:\I.S\Testoooooooo\Testoooooooo\Dataset1.xsd");
ds.WriteXml(#"G:\I.S\Testoooooooo\Testoooooooo\Dataset1.xml");
}
private DataTable getData()
{
DataSet dss = new DataSet();
SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM NewBill", cn);
da.Fill(dss);
DataTable dt = dss.Tables["NewBill"];
return dt;
}
private void runRptViewer()
{
this.reportViewer2.Reset();
//this.ReportViewer1.LocalReport.ReportPath = Server.MapPath("Report.rdlc");
this.reportViewer2.LocalReport.ReportPath =(#"G:\I.S\Testoooooooo\Testoooooooo\Report1.rdlc");
ReportDataSource rds = new ReportDataSource("dsNewDataSet_NewBill", getData());
this.reportViewer2.LocalReport.DataSources.Clear();
this.reportViewer2.LocalReport.DataSources.Add(rds);
//this.reportViewer2.DataBind();
this.reportViewer2.LocalReport.Refresh();
}
}
i have two reportViewer the reportViewer1 work but in case the directory of the db has change it will not work, so thats why i try in another reportViewer, to make it work even if the directory of the db changed, i can just change the Connection string.
The problem is the report don't show anything, i think the problem in the code:
//this.ReportViewer1.LocalReport.ReportPath = Server.MapPath("Report.rdlc");
this is a windows form so there is no server, ive change it to:
this.reportViewer2.LocalReport.ReportPath =(#"G:\I.S\Testoooooooo\Testoooooooo\Report1.rdlc");
and this one dont work:
//this.reportViewer2.DataBind();
i cant understand this two lines, does it mean to create a Dataset1.xsd and Dataset1.xml, or just edit them.
ds.WriteXmlSchema(#"G:\I.S\Testoooooooo\Testoooooooo\Dataset1.xsd");
ds.WriteXml(#"G:\I.S\Testoooooooo\Testoooooooo\Dataset1.xml");
if possible i need a steps from creating every thing to codding that will be great.
How did you create your dataset? Is it SQL or from Objects in memory?
If you havent created a dataset, you do need to create one before the report can work properly. This might help: http://shrutikapoor-ubc.blogspot.com/2013/05/using-business-objects-in-report-viewer.html
To use the report viewer in your C# WinForm project add the following code to a button or inthe form_load:
string strConnectionString = "Data Source=(local);Initial Catalog=Projects_DB;Integrated Security=True";
DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter();
SqlCommand cmd = new SqlCommand("sp_GetProject " + "'0660CAD6-6F1A-4D19-A1FD-17BF3655AC98'");
cmd.CommandType = CommandType.Text;
cmd.Connection = new SqlConnection (strConnectionString);
da.SelectCommand = cmd;
da.Fill(ds,"DataSet1");
reportViewer1.ProcessingMode = ProcessingMode.Local;
reportViewer1.LocalReport.DataSources.Clear();
reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("DataSet1", ds.Tables[0]));
reportViewer1.LocalReport.Refresh();
reportViewer1.RefreshReport();
Assuming that you have a stored procedure that accepts #ProjectID parameter. You have to set the cmd.CommandType = CommandType.Text if you pass these parameters along with the sql command. However, if you don't want to pass parameters just change the commandType to cmd.CommandType = CommandType.StoredProcedure.
Below is the stored procedure used in this example:
CREATE PROC [dbo].[sp_GetProject]
#ProjectID nvarchar(50)=NULL
AS
BEGIN
SELECT ProjectID, ProjectName FROM Projects
WHERE
(#ProjectID IS NULL) OR (ProjectID = #ProjectID)
END
Microsoft has a pretty good walkthrough here...
http://blogs.msdn.com/b/sqlforum/archive/2011/04/28/sql-reporting-services-ssrs-bind-dynamic-dataset-to-your-local-report-with-reportviewer.aspx

Returning a Dataset as an Object in a Method

I am writing a method that will query a table and return a Dataset object containing the specified column. Moreover, I have a problem with my Username & Password, so I am using Windows authentication for the same but I am not too sure about that in my snippet I have written till now.
protected void GetProgramList()
{
SqlConnection cn = new SqlConnection("server=Daffodils-PC/sqlexpress;Database=Assignment1;Trusted_Connection=Yes;");
SqlCommand cmd = new SqlCommand("SELECT ProgramName FROM Program", cn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet1 ds1 = new DataSet1();
}
I have been trying to follow official MS documentation but I am not sure where I am going? Can someone help me with some links or snippets?
I would say you have 2 options here:
1. to make a DataSet class variable, so its reference can be accessed from all over the class (set its access modifier to public so it can be accessed from other classes)
2. or create a method with its return type of DataSet. But in this case on the other side must be set to receive the DataSet as well:
//2. solution:
private void GetData()
{
//from inside some method:
DataSet ds = GetProgramList();
}
protected DataSet GetProgramList()
{
DataSet ds1 = new DataSet();
using (SqlConnection cn = new SqlConnection("server=Daffodils-PC/sqlexpress;Database=Assignment1;Trusted_Connection=Yes;"))
{
using (SqlDataAdapter da = new SqlDataAdapter(#"SELECT ProgramName FROM Program", cn))
da.Fill(ds1, "TableName1");
}
return ds1;
}
//
//1. solution:
class YourClass
{
DataSet ds1;
protected void GetProgramList()
{
SqlConnection cn = new SqlConnection("server=Daffodils-PC/sqlexpress;Database=Assignment1;Trusted_Connection=Yes;");
SqlCommand cmd = new SqlCommand("SELECT ProgramName FROM Program", cn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
ds1 = new DataSet();
}
}
Place your connection string in AppSettings section in app.config or web.config
public string GetSqlConnection()
{
return System.Configuration.ConfigurationManager.AppSettings["SqlConnectionString"];
}
public DataSet getDataSet(string sql)
{
DataSet ds = new DataSet();
SqlConnection conn = new SqlConnection(GetSqlConnection());
SqlDataAdapter da = new SqlDataAdapter(sql, conn);
da.Fill(ds);
conn.Close();
conn.Dispose();
da.Dispose();
return ds;
}
Suggestion: "use" System.Data and System.Data.SqlClient, and use a "SqlDataReader":
http://www.csharp-station.com/Tutorial/AdoDotNet/lesson04
Either read everything in your routine (generally preferred), or pass the SqlDataReader back to the caller (as a function return).
And be sure to .Close() the reader when you're done :)
SQLDataAdapter basic will get you started with the basics of creating a connection and consuming it in your code.

C# -> Retrieving dataset from SQL Server 2008

I have a table called NAMES in my SQL Server database. I am trying to retrieve the entire table and put it into a dataset:
//get the connection string from web.config
string connString = ConfigurationManager.ConnectionStrings["Platform"].ConnectionString;
DataSet dataset = new DataSet();
using (SqlConnection conn = new SqlConnection(connString))
{
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand("NAMES", conn);
adapter.Fill(dataset);
}
This throws a sql exception though,
"Invalid Object Name NAMES"...
What am I doing wrong?
Open the connection !!!!!!
//get the connection string from web.config
string connString = ConfigurationManager .ConnectionStrings["Platform"].ConnectionString;
DataSet dataset = new DataSet();
using (SqlConnection conn = new SqlConnection(connString))
{
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand("select * from [NAMES]", conn);
conn.Open();
adapter.Fill(dataset);
}
You're not passing an actual SQL select command to the SqlCommand constructor.
First check whether Select * from dbo.[Names] is wroking in ur sql ?
string connString = ConfigurationManager .ConnectionStrings["Platform"].ConnectionString;
Dataset ds=new Dataset();
SqlConnection con = new Sqlconnection(connString);
SqlDataAdapter adapter = new SqlDataAdapter("Select * from dbo.[Names]",con);
adapter.Fill(ds);

Categories