I placed my DB reader in a separate class file because I didn't want to keep rewriting it but I keep getting the error:
Object reference not set to an instance of an object. db was null
This is my DataReader:
namespace ProjectName
{
public class DBReader
{
string dsn = ConfigurationManager.ConnectionStrings["database"].ConnectionString.ToString();
public SqlDataReader SqlReader(string sql, string retDebug = "")
{
try
{
SqlConnection conn;
SqlCommand cmd;
SqlDataReader dr_user;
conn = new SqlConnection(dsn);
conn.Open();
try
{
cmd = new SqlCommand(sql, conn);
cmd.CommandType = CommandType.Text;
cmd.CommandTimeout = 180;
dr_user = cmd.ExecuteReader(CommandBehavior.CloseConnection);
return dr_user;
}
catch (SqlException ex)
{
retDebug = ex.Message;
return null;
}
conn.Close();
conn.Dispose();
}
catch (Exception ex)
{
retDebug = ex.Message;
}
return null;
}
}
}
This is where I'm catching the error...at
SqlDataReader reader = db.SqlReader(query, "");
in the code shown here:
<!DOCTYPE html>
<script runat="server">
ProjectName.DBReader db;
string projectName;
protected void Page_Load(object sender, EventArgs e)
{
LoadProjects();
}
public void LoadProjects()
{
string query = #"SELECT * FROM projects where project_type = 3;
SqlDataReader reader = db.SqlReader(query, "");
while (reader.Read())
{
//code does something here
}
}
</script>
I want to be able to reuse this because I know I will be using it many times in this project.
Any help/direction would be appreciated!
As others pointed out, like any class, you have to create a instance of that class before using.
HOWEVER, if you don't have any public vars (at least ones that will change with different users on the web site), then you can also have public members of that class, and create the class as static. (but, those public members MUST be the same for all logged on users)
So, your choice.
Always create an instance of the class before using.
eg this:
public void LoadProjects()
{
string query = #"SELECT * FROM projects where project_type = 3";
DBReader MyDB = new DBReader();
SqlDataReader reader = MyDB.SqlReader(query, "");
while (reader.Read())
{
//code does something here
}
}
Or, you can declare the class as static, like this:
(air code warning).
public static class DBReader
{
static readonly string dsn = ConfigurationManager.ConnectionStrings["database"].ConnectionString.ToString();
static public SqlDataReader SqlReader(string sql, string retDebug = "")
{
SqlDataReader dr_user = null;
using (SqlConnection conn = new SqlConnection(dsn))
{
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.CommandType = CommandType.Text;
cmd.CommandTimeout = 180;
conn.Open();
dr_user = cmd.ExecuteReader();
}
}
return dr_user;
}
}
So, now in code you don't have to create a instance.
eg:
public void LoadProjects()
{
string query = #"SELECT * FROM projects where project_type = 3";
SqlDataReader reader = MyCode.DBReader.SqlReader(query, "");
while (reader.Read())
{
//code does something here
}
}
Related
I have a code that I use to login.
I call the data I get from textbox with a method and check the records with select query in the
database.
I call to relevant method , when I press the button.
private void btnGiris_Click(object sender, EventArgs e)
{
LoginBilgiler lb = new LoginBilgiler();
bool sonuc = lb.GirisKontrol(txtAd.Text, txtSifre.Text);
}
But I encounter errors in cmd.ExecuteReader the below.
public bool GirisKontrol(string ad,string sifre)
{
using (OracleConnection con = new OracleConnection(connectionString))
{
string query = String.Format("SELECT count(*) from Z_LABEL_USER where USERNAME=({0}) and PASSWORD=({1})", ad,sifre);
OracleCommand cmd = new OracleCommand(query, con);
con.Open();
OracleDataReader dr = cmd.ExecuteReader();
if (dr.HasRows)
{
kAdi = ad;
con.Close();
return true;
}
else
con.Close();
return false;
}
}
The table I use for the select query.
Oracle.ManagedDataAccess.Client.OracleException: 'ORA-01722: invalid
number'
Please, don't hardcode parameters in SQL; parametrize it instead:
public bool GirisKontrol(string ad, string sifre) {
//DONE: validate public methods' input
if (string.IsNullOrEmpty(ad))
return false; // or throw exception
else if (string.IsNullOrEmpty(sifre))
return false; // or throw exception
using (OracleConnection con = new OracleConnection(connectionString)) {
con.Open();
//DONE: no need to count all the entires, just check if there's at least one
//DONE: keep query readable
//DONE: paramterize queries
string query =
#"select 1
from Z_LABEL_USER
where USERNAME = :prm_UserName
and PASSWORD = :prm_Password";
using (OracleCommand cmd = new OracleCommand(query, con)) {
//TODO: this syntax can vary from library to library you use to work with Oracle
cmd.Parameters.Add(":prm_UserName", OracleType.VarChar).Value = ad;
cmd.Parameters.Add(":prm_Password", OracleType.VarChar).Value = sifre;
using (OracleDataReader dr = cmd.ExecuteReader()) {
if (dr.Read()) {
//TODO: Side effect : it changes instance's state. Do you really want it?
kAdi = ad;
return true;
}
}
}
}
return false;
}
I have a Class that processes DB column metadata. One of the Properties of the Class is the table in question. This is passed to the object via the constructor. Also in the constructor I apply some logic to assign other variables within the class. To do this there are a number of private methods that connect to a DB, query something about the table, and return a value to the variable.
My problem is that I have a lot of different methods doing pretty much the same thing, but returning a different datatype. So for example my code is something like this
public Column(string tableName)
{
strTableName = tableName;
pkColumnName = GetPKColumnName(tableName);
pkColumnLenght = GetPKColumnLenght(tableName);
}
private string GetPKColumnName(string tableName)
{
string query = String.Format("SELECT myColName FROM myTable where myTableName = {0}", tableName);
string result = "";
try
{
using(SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString))
{
con.Open();
using (SqlCommand command = new SqlCommand(query, con))
{
result = (string)command.ExecuteScalar();
}
}
}
catch (SqlException ex)
{
Console.WriteLine(ex.Message);
}
return result;
}
private int GetPKColumnLenght(string tableName)
{
string query = String.Format("SELECT myColLenght FROM myTable where myTableName = {0}", tableName);
int result = 0;
try
{
using(SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString))
{
con.Open();
using (SqlCommand command = new SqlCommand(query, con))
{
result = (int)command.ExecuteScalar();
}
}
}
catch (SqlException ex)
{
Console.WriteLine(ex.Message);
}
return result;
}
There are many other methods like this also. This didn't look great to me, so I was wondering what the best practice was for something like this.
Should I just declare the return type as an object and do the datatype conversions when assigning the returned value to my variable?
My answer and the other assume different questions. It appears to me that you are trying to query a single value from a specific column and that you have to create a new method because the types are different. That said, I would personally just use a simple ORM solution and the other answer certainly is not wrong, just another abstraction.
You will want to use generics and cast to the generic.
I haven't tested this code, it is more of a guideline.
private T GetValue<T>(string tableName, colName)
{
string query = String.Format("SELECT {0} FROM myTable where myTableName = {1}", colName, tableName);
T result = default(T);
try
{
using(SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString))
{
con.Open();
using (SqlCommand command = new SqlCommand(query, con))
{
result = (T)command.ExecuteScalar();
}
}
}
catch (SqlException ex)
{
Console.WriteLine(ex.Message);
}
return result;
}
Create SqlManager class
public class SqlManager
{
public static string ConnectionString
{
get
{
return "Your ConnectionString"
}
}
public static SqlConnection GetSqlConnection(SqlCommand cmd)
{
if (cmd.Connection == null)
{
SqlConnection conn = new SqlConnection(ConnectionString);
conn.Open();
cmd.Connection = conn;
return conn;
}
return cmd.Connection;
}
public static object ExecuteScalar(SqlCommand cmd)
{
SqlConnection conn = GetSqlConnection(cmd);
try
{
return cmd.ExecuteScalar();
}
catch
{
throw;
}
finally
{
conn.Close();
}
}
}
Now your methods, for the second one same thing:
private string GetPKColumnName(string tableName)
{
string query = String.Format("", tableName);
SqlCommand cmd = new SqlCommand();
cmd.CommandText = #"SELECT myColName FROM myTable where myTableName = #TableName";
cmd.Parameters.AddWithValue("#TableName", tableName);
object result = SqlManager.ExecuteScalar(cmd);
return result != null ? (int)object: 0;
}
I want to read data from an oracle database and add that data in to a List. But when I run the application I'm getting the 'Invalid operation. The connection is closed.' error.
This is my code:
public class NewOtherCompanyMapper
{
OtherCompany om;
private Database db;
private DbCommand cmd;
private DbConnection con;
public NewOtherCompanyMapper(OtherCompany om_temp)
{
om = om_temp;
db = DatabaseFactory.CreateDatabase("NDA_generator");
}
public List<OtherCompany> getCompanyDetails()
{
List<OtherCompany> list = new List<OtherCompany>();
OtherCompany oc = new OtherCompany();
try
{
con = db.CreateConnection();
con.Open();
string query = "SELECT * FROM OtherCompanyData";
cmd = db.GetSqlStringCommand(query);
DbDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
oc = new OtherCompany(reader["RegNumber"].ToString(), reader["ComName"].ToString(), reader["Country"].ToString(), reader["Address"].ToString(), reader["CoreBusi"].ToString());
list.Add(oc);
}
}
catch (Exception ex)
{
throw ex;
}
return list;
}
}
Can you please help me to solve this problem.
Try replacing this
cmd = db.GetSqlStringCommand(query);
with this:
cmd = con.CreateCommand();
cmd.CommandText = query;
this is how I try to print something worthwhile for my site using my class, When I try to write my class will not find it at all.
I can not find my worth to return something worthwhile for my user.
the problem is that it can not find at all class.
My class:
public class AbonnementsId
{
public int indhold { get; set; }
}
public AbonnementsId HentAbonnementsId()
{
AbonnementsId AbonnementsidReturn = new AbonnementsId();
AbonnementsidReturn.indhold = 0;
SqlConnection conn1 = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ToString());
SqlCommand cmd1 = conn1.CreateCommand();
cmd1.Connection = conn1;
int brugerid = Convert.ToInt32(HttpContext.Current.Session["id"]);
cmd1.CommandText = #"SELECT abonnementsid from brugere WHERE id = #id";
cmd1.Parameters.AddWithValue("#id", brugerid);
conn1.Open();
SqlDataReader readerBrugerA = cmd1.ExecuteReader();
if (readerBrugerA.Read())
{
AbonnementsidReturn.indhold = Convert.ToInt32(readerBrugerA["abonnementsid"]);
}
conn1.Close();
return AbonnementsidReturn;
}
Here is how I write my class out when I need it for my content.
if (Session["AbonnementsId"] != null)
{
_subscriptionId = long.Parse(Session["AbonnementsId"].ToString());
}
else
{
//when I need to print my class do I like it here
_subscriptionId = AbonnementsidReturn.indhold();
}
I'm totally shooting in the dark here:
public static class AbonnementsId
{
public static int GetAbonnementsId()
{
int abonnementsid;
string connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ToString();
using(var conn = new SqlConnection(connectionString))
{
int brugerid = Convert.ToInt32(HttpContext.Current.Session["id"]);
SqlCommand cmd1 = conn.CreateCommand();
cmd1.Connection = conn;
cmd1.CommandText = #"SELECT abonnementsid from brugere WHERE id = #id";
cmd1.Parameters.AddWithValue("#id", brugerid);
conn.Open();
SqlDataReader readerBrugerA = cmd1.ExecuteReader();
if (readerBrugerA.Read())
abonnementsid = Convert.ToInt32(readerBrugerA["abonnementsid"]);
conn.Close();
}
return abonnementsid;
}
}
You can then call this in your code:
if (Session["AbonnementsId"] != null)
{
_subscriptionId = long.Parse(Session["AbonnementsId"].ToString());
}
else
{
//when I need to print my class do I like it here
_subscriptionId = AbonnementsId.GetAbonnementsId();
}
I have designed my application in a layered approach. I have a BusinessOP layer for each interface and a common data access layer. In my Data access layer I have Data Reader method like this.|
public SqlDataReader executeQuerys(string query01)
{
SqlConnection con = null;
SqlCommand com = null;
try
{
con = new SqlConnection(DBConnect.makeConnection());
con.Open();
com = new SqlCommand(query01, con);
return com.ExecuteReader(CommandBehavior.CloseConnection);
}
catch
{
com.Dispose();
con.Close();
throw;
}
This is the code for my DBConnection layer.
public static string makeConnection()
{
string con = ConfigurationManager.ConnectionStrings["MyDB.Properties.Settings.ConString"].ToString();
return con;
}
In my business layer I have methods like this each calling a specific stored procedure.
public SqlDataReader getLGDivID(string divName)
{
string query = "EXEC getLGDivID'" + divName + "'";
return new DataAccessLayer().executeQuerys(query);
}
As my business operation layer is unsecure, I want to have it with parameterized query in here I'm using string concatenation to pass parameters. Can anyone hint me how to modify it?
You can change your function a little bit:
public SqlDataReader executeQuerys(string query01, string paramName, string value)
{
SqlConnection con = null;
SqlCommand com = null;
try
{
con = new SqlConnection(DBConnect.makeConnection());
con.Open();
com = new SqlCommand(query01, con);
com.Parameters.AddWithValue(paramName, value);
com.Dispose();
con.Close();
}
catch
{
com.Dispose();
con.Close();
throw;
}
return com.ExecuteReader(CommandBehavior.CloseConnection);
}
then to use it:
public SqlDataReader getLGDivID(string divName)
{
string query = "EXEC getLGDivID #divName";
return new DataAccessLayer().executeQuerys(query, "#divName", divName);
}
EDIT:
As #silvermind pointed out, you should dispose your connection properly.
The way you have it now it will dispose connection only when you catch an exception.
This is bad, make use of IDisposable, for example:
public SqlDataReader executeQuerys(string query01, string paramName, string value)
{
using (SqlConnection con = new SqlConnection(DBConnect.makeConnection()))
{
try
{
con.Open();
com = new SqlCommand(query01, con);
com.Parameters.AddWithValue(paramName, value);
}
catch(SqlException ex)
{
//Handle the exceptio
//no need to dispose connection manually
//using statement will take care of that
}
}
return com.ExecuteReader(CommandBehavior.CloseConnection);
}