Returning result of SqlCommand in class - c#

As I'm not programming long time I would like to ask you if there is way to call result of this SqlCommand which is in class called klientClass
I was thinking that it could look something like this:
private static void ReadFirma()
{
string queryString =
"SELECT rocnik from FIRMA;";
using (SqlConnection connection = new SqlConnection(myConnection.DataSource.ConnectionString
))
{
SqlCommand command = new SqlCommand(
queryString, connection);
connection.Open();
int result= Convert.ToInt32(command.ExecuteScalar());
try
{
}
finally
{
reader.Close();
}
}
}
Because I need to insert this result into my report parameter here:
this.klientTableAdapter.Fill(this.prehled_zajezdu.HereReturnResult);
this.reportViewer1.RefreshReport();
I'm sorry for quiet low-quality question, hope not to receive down-votes.

This is how you can retrieve and use the value from the database in your Fill method (provided that the Fill method takes an argument of the type int and that the myConnection field is available from the static method)
private static int ReadFirma()
{
string queryString = "SELECT rocnik from FIRMA";
using (var connection =
new SqlConnection(myConnection.DataSource.ConnectionString))
using(var command = new SqlCommand(queryString, connection))
{
connection.Open();
return Convert.ToInt32(command.ExecuteScalar());
}
}
void SomeMethod()
{
this.klientTableAdapter.Fill(ReadFirma());
}

You can use DataTable object for your Goal.
private static DataTable ReadFirma()
{
string queryString = "SELECT rocnik from FIRMA";
using (var connection =
new SqlConnection(myConnection.DataSource.ConnectionString))
using(var command = new SqlCommand(queryString, connection))
{
connection.Open();
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = command;
da.Fill(dt);
return dt;
}
}
void SomeMethod()
{
this.klientTableAdapter.Fill(ReadFirma());
}

Related

Why do I get the error "Cannot Implicitly convert type 'Form.QueryExecute' to 'string'." when creating a DB connection in C#?

I'm trying to architect the structure of code for a DB connection. I've created a class which I called 'DbConn.cs':
class DbConn
{
public SqlConnection getDbConnection()
{
String connectionString = "Data Source=172.26.187.34, 1181;Initial Catalog=LoansDev;User ID=AppUser;Password=Passw0rd";
SqlConnection conn = new SqlConnection(connectionString);
return conn;
}
public bool isConnectionEstablish()
{
try
{
getDbConnection();
return true;
}
catch(Exception e)
{
return false;
}
}
}
Now every time I try to execute a query I'll just call the class DbConn conn = new DbConn(); then I'll use the conn.getDbConnection().open() to open and connection and vice versa. I don't know if it's a proper way of handling connections since all tutorials I've seen is the handler for connection is also where the query is being executed.
Now I have a class 'QueryExecute.cs' which will hold all my queries.
The problem is if try to call the method on my form, I always get the error
"Cannot Implicitly convert type 'Form.QueryExecute' to 'string'.
Here is the code for my form:
StatusViewForm.cs:
private void StatusViewForm_Load(object sender, EventArgs e)
{
// frmLogin loginForm = new frmLogin();
//String loggedUser = loginForm.getUserID;
//MessageBox.Show(LoggedUser, "Who is logged in?", MessageBoxButtons.OK);
QueryExecute taskEmp = new QueryExecute();
DbConn dbConn = new DbConn();
DataTable dt = new DataTable();
String userID = taskEmp.getEmployeeDetails(userID: LoggedUser);
String query = taskEmp.getTaskDetails(LoggedUser);
//MessageBox.Show(query, "Query", MessageBoxButtons.OK);
SqlDataAdapter da = new SqlDataAdapter(query, dbConn.getDbConnection());
dbConn.getDbConnection().Open();
da.Fill(dt);
dbConn.getDbConnection().Close();
dgvTaskView.DataSource = dt;
}
Then here is my QueryExecute.cs:
public QueryExecute getEmployeeDetails(String userID)
{
DataTable empDetails = new DataTable("EmployeeDetails");
QueryExecute empInfo = new QueryExecute();
DbConn conn = new DbConn();
using (conn.getDbConnection())
{
String query = "SELECT * FROM dbo.Employee WHERE UserID = '" + userID + "'";
SqlCommand cmd = new SqlCommand(query, conn.getDbConnection());
cmd.Parameters.AddWithValue("#UserID", userID);
conn.getDbConnection().Open();
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = cmd;
da.Fill(empDetails);
if(empDetails.Rows.Count > 0)
{
empInfo.UserID = (string)empDetails.Rows[0]["UserID"];
empInfo.Name = (string)empDetails.Rows[0]["Name"];
empInfo.IsAdmin = (bool)empDetails.Rows[0]["IsAdmin"];
}
conn.getDbConnection().Close();
}
return empInfo;
}
I'm wondering if it's my DbConn class that is causing the problem...

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"];
}
}
}

Calling a Stored procedure

I'm new to C# I need to call a SP and return the table value from C#.
I'm passing current datetime(#currentdate) as my input parameter in the stored procedure.So how do I pass this in C# method?
Pls help me to write a C# method to call that SP and return the value
I have my sp ready. sp will return the top updated record in the table.
I have used this in my C# code
string _Num = null;
SqlConnection sqlConnection1 = new SqlConnection("Data Source=localhost;Initial Catalog=ReferenceDB;Persist Security Info=True;Integrated Security=SSPI");
SqlCommand cmd = new SqlCommand();
Int32 rowsAffected;
Object returnValue;
cmd.CommandText = "Number";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#CurrentDate", DateTime.Now);
cmd.Connection = sqlConnection1;
sqlConnection1.Open();
rowsAffected = cmd.ExecuteNonQuery();
returnValue = cmd.ExecuteScalar();
if (returnValue != null)
_Num = returnValue.ToString();
return _Num
Write his code in that method
SqlConnection con = new SqlConnection("coonectionstring");
SqlCommand cmd = new SqlCommand();
SqlCommand cmd = new SqlCommand("Your sp",con);
cmd.CommandType = CommandType.StoredProcedure;
//input parameters
cmd.Parameters.Add(new SqlParameter("#currentdate",SqlDbType.DateTime,"currentdate"));
int i=command.ExecuteNonQuery();
If you are going to use more than one sp in your C# code, I suggest something like this:
public static DataTable GetSQLValues(string currentDate)
{
SqlParameter[] sqlParams =
{
new SqlParameter("#currentDate", currentDate)
};
return DBHelper.GetTable("MSSQLSPNAME", sqlParams);
}
Use the above for every instance where you need to get table info.
GetTable looks like this:
static SqlConnection _conn;
static string _connStr = ConfigurationManager.ConnectionStrings[ConfigurationManager.AppSettings["primaryConnStr"]].ToString();
static SqlCommand _cmd;
static SqlDataAdapter _dataAdapter = new SqlDataAdapter();
public static DataTable GetTable(string sProcName, SqlParameter[] sqlParams)
{
using (_conn = new SqlConnection(_connStr))
{
_cmd = new SqlCommand(sProcName, _conn);
_conn.Open();
_cmd.CommandType = CommandType.StoredProcedure;
if (sqlParams != null)
{
_cmd.Parameters.AddRange(sqlParams);
}
_dataAdapter = new SqlDataAdapter(_cmd);
var results = new DataTable();
_dataAdapter.Fill(results);
_conn.Close();
return results;
}
}
It will save you a ton of time for each sp call you need from C#.

How to get list of all database from sql server in a combobox using c#.net

I am entering the source name userid and password through the textbox and want the database list should be listed on the combo box so that all the four options sourcename, userid, password and databasename can be selected by the user to perform the connectivity
The databases are to be retrieve from other system as per the user. User will enter the IP, userid and password and they should get the database list in the combo box so that they can select the required database and perform the connectivity
private void frmConfig_Load(object sender, EventArgs e)
{
try
{
string Conn = "server=servername;User Id=userid;" + "pwd=******;";
con = new SqlConnection(Conn);
con.Open();
da = new SqlDataAdapter("SELECT * FROM sys.database", con);
cbSrc.Items.Add(da);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
I am trying to do this but it is not generating any data
sys.databases
SELECT name
FROM sys.databases;
Edit:
I recommend using IDataReader, returning a List and caching the results. You can simply bind your drop down to the results and retrieve the same list from cache when needed.
public List<string> GetDatabaseList()
{
List<string> list = new List<string>();
// Open connection to the database
string conString = "server=xeon;uid=sa;pwd=manager; database=northwind";
using (SqlConnection con = new SqlConnection(conString))
{
con.Open();
// Set up a command with the given query and associate
// this with the current connection.
using (SqlCommand cmd = new SqlCommand("SELECT name from sys.databases", con))
{
using (IDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
list.Add(dr[0].ToString());
}
}
}
}
return list;
}
First add following assemblies:
Microsoft.SqlServer.ConnectionInfo.dll
Microsoft.SqlServer.Management.Sdk.Sfc.dll
Microsoft.SqlServer.Smo.dll
from
C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\
and then use below code:
var server = new Microsoft.SqlServer.Management.Smo.Server("Server name");
foreach (Database db in server.Databases) {
cboDBs.Items.Add(db.Name);
}
you can use on of the following queries:
EXEC sp_databases
SELECT * FROM sys.databases
Serge
Simply using GetSchema method:
using (SqlConnection connection = GetConnection())
{
connection.Open();
DataTable dtDatabases = connection.GetSchema("databases");
//Get database name using dtDatabases["database_name"]
}
using (var connection = new System.Data.SqlClient.SqlConnection("ConnectionString"))
{
connection.Open();
var command = new System.Data.SqlClient.SqlCommand();
command.Connection = connection;
command.CommandType = CommandType.Text;
command.CommandText = "SELECT name FROM master.sys.databases";
var adapter = new System.Data.SqlClient.SqlDataAdapter(command);
var dataset = new DataSet();
adapter.Fill(dataset);
DataTable dtDatabases = dataset.Tables[0];
}
How to get list of all database from sql server in a combobox using c# asp.net windows application
try
{
string Conn = "server=.;User Id=sa;" + "pwd=passs;";
SqlConnection con = new SqlConnection(Conn);
con.Open();
SqlCommand cmd = new SqlCommand();
// da = new SqlDataAdapter("SELECT * FROM sys.database", con);
cmd = new SqlCommand("SELECT name FROM sys.databases", con);
// comboBox1.Items.Add(cmd);
SqlDataReader dr;
dr = cmd.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
//comboBox2.Items.Add(dr[0]);
comboBox1.Items.Add(dr[0]);
}
}
// .Items.Add(da);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Try this:
SqlConnection con = new SqlConnection(YourConnectionString);
SqlCommand cmd = new SqlCommand("SELECT name from sys.databases", con);
con.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
cbSrc.Items.Add(dr[0].ToString());
}
con.Close();
or this:
DataSet ds = new DataSet();
SqlDataAdapter sqlda = new SqlDataAdapter("SELECT name from sys.databases", YourConnectionString);
sqlda.Fill(ds);
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
cbSrc.Items.Add(ds.Tables[0].Rows[i][0].ToString());
}
public static List<string> GetAllDatabaseNamesByServerName(string ServerName, [Optional] string UserID, [Optional] string Password)
{
List<string> lstDatabaseNames = null;
try
{
lstDatabaseNames = new List<string>();
//string servername = System.Environment.MachineName;
string newConnString = string.Format("Data Source={0};", ServerName);
if (UserID == null)
{
newConnString += "Integrated Security = True;";
}
else
{
newConnString += string.Format("User Id ={0}; Password={1};", UserID, Password);
}
SqlConnection con = new SqlConnection(newConnString);
con.Open();
SqlCommand cmd = new SqlCommand("SELECT name FROM master.sys.databases", con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
foreach (DataRow row in dt.Rows)
{
lstDatabaseNames.Add(row[0].ToString());
}
con.Close();
return lstDatabaseNames;
}
finally
{
}
}

C# - Increase method reusability

private static void ReadOrderData(string connectionString)
{
string queryString =
"SELECT OrderID, CustomerID FROM dbo.Orders;";
using (SqlConnection connection =
new SqlConnection(connectionString))
{
SqlCommand command =
new SqlCommand(queryString, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
// Call Read before accessing data.
while (reader.Read())
{
Console.WriteLine(String.Format("{0}, {1}",
reader[0], reader[1]));
}
// Call Close when done reading.
reader.Close();
}
}
How can I enhance the method above to accept any queryString? The problem is in the while. There's a fixed # of columns I can read. I want to be able to read any number of columns so that I can populate and return a DataSet. How can I do it?
You can do something along these lines:
private static void ReadOrderData(string connectionString,
string query, Action<SqlDataReader> action)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command =
new SqlCommand(query, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
// Call Read before accessing data.
while (reader.Read())
{
action(reader);
}
// Call Close when done reading.
reader.Close();
}
}
You're really barking up the wrong tree. You shouldn't be using "methods that accept query strings". You should raise the level of abstraction by using Entity Framework or the like.
You will then not need to use the above code because it will not exist. Those who would have called that code will do something like this:
var orders = from o in ordersDAL.Orders
select new {o.OrderID, o.CustomerID};
foreach (var order in orders)
{
Console.WriteLine("{0}, {1}", order.OrderID, order.CustomerID);
}
Your code is badly designed in any case. Why in the world would you combine the fetching of the data with the use of it? That while loop should not be in that same method.
I would use something like the answer from obrok, but I would add the ability to use parameters.
Also, the SqlCommand and SqlDataReader both need to be within a using block:
private static void ReadOrderData(string connectionString,
string query, Action<SqlDataReader> action)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (SqlCommand command =
new SqlCommand(query, connection)) {
connection.Open();
using (SqlDataReader reader = command.ExecuteReader()) {
// Call Read before accessing data.
while (reader.Read())
{
action(reader);
}
// No need to call Close when done reading.
// reader.Close();
} // End SqlDataReader
} // End SqlCommand
}
}
Use SqlDataAdapter:
private static DataSet ReadData(string connectionString, string queryString)
{
DataSet dataSet;
using (SqlConnection connection =
new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command =
new SqlCommand(queryString, connection);
SqlDataAdapter adapter = new SqlDataAdapter(command);
adapter.Fill(dataSet);
}
return dataSet;
}
Or something like this.
How I'm doing this:
(basically idea is to use DataSet along with IDataAdapter)
DataSet ds = null;
List<SqlParameter> spParams = ...
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
using (SqlCommand command = new SqlCommand(spName, connection))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Clear();
command.Parameters.AddRange(spParams);
connection.Open();
IDbDataAdapter da = new SqlDataAdapter();
da.SelectCommand = command;
ds = new DataSet("rawData");
da.Fill(ds);
ds.Tables[0].TableName = "row";
foreach (DataColumn c in ds.Tables[0].Columns)
{
c.ColumnMapping = MappingType.Attribute;
}
}
}
// here is you have DataSet flled in by data so could delegate processing up to the particular DAL client
You said you tried EF, but did you try Dapper ? looks like a simple enough ORM that should work with your database (it's raw SQL), and will avoid you most of this mapping code. Dapper is used in StackOverflow so it cannot be too bad :)
Same suggestion as 'WorkerThread' but change the Method Signature to:
private static DataSet ReadOrderData(string connectionString, string queryString)
{
// do work
}
Drop the following line from 'WorkerThread' example:
string queryString = "SELECT OrderID, CustomerID FROM dbo.Orders;";
Once you have made these two changes to 'WorkerThread's' method it should be perfect for what you need.
Look at the DataTable.Load method. Or, for a finer level of control, check out the properties and methods on IDataReader, such as FieldCount, GetFieldType, and GetName.

Categories