I want to create a class that I can get datatable of specific table given in the parameter of the constructor.
But how I can do it without it being vulnerable to SQL Injections?
I would've done something like this: (But you can't use those statements like that)
public class SqlClass
{
DataTable dt;
string table;
public SqlClass(String table)
{
this.table = table;
SqlConnection c = new SqlConnection();
c.conOpen();
MySqlCommand msc = new MySqlCommand("SELECT * FROM #tableName", c.Con); //Cant do that
msc.Parameters.AddWithValue("#tableName", table);
DataSet ds = c.getDataSet(msc, table);
this.dt = ds.Tables[table];
c.conClose();
}
public DataTable Dt { get => dt; set { dt = value; } }
}
Any other working alternative that won't harm me? Thanks.
Related
I have a table and I want to get specific column from my dataset my table only has one row.
Here is my code
private DataSet Ds = new DataSet();
public DataSet GetDataSet(string Query)
{
try
{
using (MySqlConnection conn = new MySql.Data.MySqlClient.MySqlConnection(connString))
{
MySqlDataAdapter Da = new MySqlDataAdapter(Query, conn);
Da.Fill(Ds);
conn.Close();
}
}
catch (Exception) { }
return Ds; //See image
}
public string getDataCellString(string headerName)
{
return "";//I want to get cell from heder name
}
Here is my question: How can I get a cell value from a header name?
If you only have one row you can:
public string getDataCellString(string headerName)
{
return Ds.Tables[0].Rows[0][headerName].ToString();
}
`Ds.Tables[0].Rows[0]["headerName"].ToString();
I have two DataTables after passing query the second DataTable Shows the FirstDataTable values. Please find my code
My connection class is
public class Connection
{
conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString);
public SqlDataAdapter ad;
public DataTable dt = new DataTable();
public DataTable gettable(string cmdtxt)
{
if (conn.State == ConnectionState.Open)
{
conn.Close();
}
conn.Open();
dt.Clear();
ad = new SqlDataAdapter(cmdtxt, conn);
ad.Fill(dt);
return dt;
}
}
My code is
String qry="";
DataTable shiftdt = new DataTable();
DataTable empdt = new DataTable();
qry = "select ShiftID from ShiftGroup where ShiftName="#Shift";
shiftdt = conn.gettable(qry);
qry = "select EmpCode from EmployeeShift where GroupCode="#gcode";
empdt = conn.gettable(qry);
First,shiftdt shows proper output ShiftID and when go ahead empdt shows first column as ShiftID and Second Column as EmpCode. Actually I dont want ShiftID in empdt. And again when I go ahead Shiftdt values changes to EmpCode. May I know the reason?
I tried `Dot net learner,when I change code as per him, I have a
dropdown class it shows error like
`Error 8 'Sample.Connection' does not contain a definition for 'dt' and no extension method 'dt' accepting a first argument of type 'Sample.Connection' could be found (are you missing a using directive or an assembly reference?
. That calss is
public class Dropdown
{
Connection con = new Connection();
public void dropdwnlist(string qry, DropDownList ddl)
{
con.gettable(qry);
if (con.dt.Rows.Count > 0)
{
if (con.dt.Columns.Count == 2)
{
string str1 = con.dt.Columns[0].ColumnName.ToString();
string str2 = con.dt.Columns[1].ColumnName.ToString();
ddl.DataValueField = str1;
ddl.DataTextField = str2;
ddl.DataSource = con.dt;
ddl.DataBind();
con.dt.Columns.Remove(str1);
con.dt.Columns.Remove(str2);
}
else
{
string str = con.dt.Columns[0].ColumnName.ToString();
ddl.DataValueField = str;
ddl.DataTextField = str;
ddl.DataSource = con.dt;
ddl.DataBind();
con.dt.Columns.Remove(str);
}
}
ddl.Items.Insert(0, ("--Select--"));
}
}
You Have dt as Global variable in Class So Please Make it Local variable for Function or Assign new DataTable on starting of gettable function.
Your revised Code should be
public class Connection
{
conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString);
public SqlDataAdapter ad;
public DataTable gettable(string cmdtxt)
{
DataTable dt = new DataTable();
if (conn.State == ConnectionState.Open)
{
conn.Close();
}
conn.Open();
dt.Clear();
ad = new SqlDataAdapter(cmdtxt, conn);
ad.Fill(dt);
return dt;
}
}
I had revised code as per your need please check it.
You shouldn't use Connection Class DataTable(dt) Variable to bind dropdown instead Declare DataTable Variable Local for Dropdown Class and use it to bind Dropdown.
Revised Code for Dropdown Class
public class Dropdown
{
Connection con = new Connection();
public void dropdwnlist(string qry, DropDownList ddl)
{
DataTable dt =con.gettable(qry);
if (dt.Rows.Count > 0)
{
if (dt.Columns.Count == 2)
{
string str1 = dt.Columns[0].ColumnName.ToString();
string str2 = dt.Columns[1].ColumnName.ToString();
ddl.DataValueField = str1;
ddl.DataTextField = str2;
ddl.DataSource = dt;
ddl.DataBind();
dt.Columns.Remove(str1);
dt.Columns.Remove(str2);
}
else
{
string str = dt.Columns[0].ColumnName.ToString();
ddl.DataValueField = str;
ddl.DataTextField = str;
ddl.DataSource = dt;
ddl.DataBind();
dt.Columns.Remove(str);
}
}
ddl.Items.Insert(0, ("--Select--"));
}
}
I have a stored procedure which actually concatenates 2 columns and returns a DataTable.
Its as below:
create procedure [dbo].[spEnqIDFyYear]
as
begin
select CONVERT(nvarchar(50),enq_id)+'/'+CONVERT(nvarchar(50),YEAR(fy_year)) as EnqIDFyYear from Sample.dbo.enquiry_details
end
GO
The output is as follows:
EnqIDFyYear
1/2015
2/2014
I have another procedure, whose output is as below:
profile_name
ProfileA
ProfileB
I bind both the procedures to 2 DataTables, merge those 2 DataTables into a 3rd one and bind the resulting DataTable to the gridview.
But the gridview is not showing as proper. It shows as below:
The rows should be aligned to each other. How to achieve it?
Code behind is as below:
protected void Page_Load(object sender, EventArgs e)
{
DataTable dt1 = PopulateDashBoardGrid1();
DataTable dt2 = PopulateDashBoardGrid2();
DataTable dt3 = new DataTable();
dt3 = dt1.Copy();
dt3.Merge(dt2);
GridView1.DataSource = dt3;
GridView1.DataBind();
}
//Populate the main DashBoard Grid
public DataTable PopulateDashBoardGrid1()
{
using (SqlConnection con = new SqlConnection(cs))
{
SqlDataAdapter da = new SqlDataAdapter("spEnqIDFyYear", con);
DataTable dt = new DataTable();
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.Fill(dt);
return dt;
}
}
public DataTable PopulateDashBoardGrid2()
{
using (SqlConnection con = new SqlConnection(cs))
{
SqlDataAdapter da = new SqlDataAdapter("spClientProfileName", con);
DataTable dt = new DataTable();
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.Fill(dt);
return dt;
}
}
Experts please help.
Regards
Anurag
You are getting that kind of output, because Merge works in that way if the columns are not same of two datatables. So you need to write some custom code.
Here is what I have:-
static DataTable MergeDataTables(DataTable dt1, DataTable dt2)
{
DataTable dt3 = dt1.Copy();
foreach (DataColumn dc in dt2.Columns)
{
dt3.Columns.Add(dc.ColumnName).DataType = dc.DataType;
}
for (int i = 0; i < dt3.Rows.Count; i++)
{
foreach (DataColumn dc in dt2.Columns)
{
string col = dc.ColumnName;
dt3.Rows[i][col] = dt2.Rows[i][col];
}
}
return dt3;
}
You can call this method to merge both datatables.
I have table called Inventory, and I want to remove the first row of it. For that purpose I have created a class named InventoryDAL. Here's code:
public class InventoryDAL
{
private string cnString = string.Empty;
private SqlDataAdapter da = null;
public InventoryDAL(string connectionString)
{
cnString = connectionString;
da = new SqlDataAdapter("Select CarID, Make, Color, PetName From Inventory",
connectionString);
SqlCommandBuilder builder = new SqlCommandBuilder(da);
da.DeleteCommand = builder.GetDeleteCommand();
da.InsertCommand = builder.GetInsertCommand();
da.UpdateCommand = builder.GetUpdateCommand();
}
public DataTable Inventory()
{
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}
public void UpdateInventory(DataTable modifiedTable)
{
da.Update(modifiedTable);
}
}
Also I created small program to try it:
class Program
{
static void Main(string[] args)
{
InventoryDAL inv = new InventoryDAL(#"Data Source=MYPC;Initial Catalog=AutoLot;Integrated Security=True;Pooling=False");
DataTable dt = inv.Inventory();
dt.Rows.RemoveAt(0);
inv.UpdateInventory(dt);
Console.ReadKey(true);
}}
But it's not working. After some attempts I realized that .Update() works only when I insert data.
Using DataTable.RemoveAt() completely removes the row from a DataTable object, so the SqlDataAdapter doesn't know to delete it at the data source. You have to use the DataTable.Rows[x].Delete() method. This marks the row for deletion so the adapter then knows to call the SQL delete statement on it.
So your code should become:
class Program
{
static void Main(string[] args)
{
InventoryDAL inv = new InventoryDAL(#"Data Source=MYPC;Initial Catalog=AutoLot;Integrated Security=True;Pooling=False");
DataTable dt = inv.Inventory();
dt.Rows[0].Delete();
inv.UpdateInventory(dt);
Console.ReadKey(true);
}
}
See here for more on how changes get pushed back to the data source.
I have some difficulty with the following: I have a dataset that I want to use to update the database when a change of value is made in the gridView. The dataset comes from the following method:
public static DataSet Display_all_members()
{
ds = new DataSet();
try
{
string query = "SELECT date_to, last_name ,first_name , member_pay FROM Member ";
conS.Open();
adapter = new SqlDataAdapter(query, conS);
adapter.Fill(ds, "To_display");
}
catch (Exception r)
{}
finally
{
conS.Close();
}
return ds;
}
In the form I do
ds2 = DAL.Display_all_members ();
dataGridView1.DataSource = ds2;
dataGridView1.DataMember = "To_display";
now I get to update and I do the following in the form
if (ds2.HasChanges() == true)
{
DAL.update(ds2);
}
In the method
public static void update(DataSet ki)
{
SqlCommandBuilder n = new SqlCommandBuilder(da);
da.Update(ds);
}
And it doesn’t work. What’s the problem?
This is the error: Update unable to find TableMapping['Table'] or DataTable 'Table'.
It might be just a typo, but your update method is using two different variables - DataSet ki, and da in the DataAdapter.Update() call.
Try this:
protected void update(DataSet ds)
{
da.Update(ds, 'To_display")
}
From DataAdapter DataTable and DataColumn Mappings (ADO.NET):
"If you do not specify a TableName or a DataTableMapping name when calling the Fill or Update method of the DataAdapter, the DataAdapter looks for a DataTableMapping named "Table". If that DataTableMapping does not exist, the TableName of the DataTable is "Table"."
If you're using the same DataSet that you originally filled, you'll probably want to keep specifying the table name where required to avoid this error.