Dynamically choose which class to use within function - c#

Is there a way to choose which class to use in a function based on how it is called? My question is best explained by code samples:
I have 2 separate files for dealing with each type of database (SQL, Access)
Access:
public static DataTable Select(string connString, string query, Dictionary<string, object> Parameters = null)
{
DataTable dt = new DataTable();
//Create Query
using (OleDbConnection conn = new OleDbConnection(connString))
using (OleDbCommand cmd = new OleDbCommand(query, conn))
using (OleDbDataAdapter da = new OleDbDataAdapter(cmd))
{
//Add Parameters
if (Parameters != null)
{
foreach (KeyValuePair<string, object> kvp in Parameters)
{
cmd.Parameters.AddWithValue(kvp.Key, kvp.Value);
}
}
//Execute Query
conn.Open();
da.Fill(dt);
return dt;
}
}
SQL:
public static DataTable Select(string connString, string query, Dictionary<string, object> Parameters = null)
{
DataTable dt = new DataTable();
//Create Query
using (SqlConnection conn = new SqlConnection(connString))
using (SqlCommand cmd = new SqlCommand(query, conn))
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
//Add Parameters
if (Parameters != null)
{
foreach (KeyValuePair<string, object> kvp in Parameters)
{
cmd.Parameters.AddWithValue(kvp.Key, kvp.Value);
}
}
//Execute Query
conn.Open();
da.Fill(dt);
return dt;
}
}
Notice the only difference is the type of the Connection, Command and Adapter.
Is there a way to merge these two functions so I can pass a parameter to specify which type to use?

What you ASKED for is called Double Dispatch. You don't need double dispatch.
public static DataTable Select(DbProviderFactory factory, string connString, string query, Dictionary<string, object> Parameters = null)
{
DataTable dt = new DataTable();
//Create Query
using (DbConnection conn = factory.CreateConnection())
{
conn.ConnectionString = connectionString;
using(DbCommand cmd = conn.CreateCommand())
using(DbDataAdapter da = factory.CreateDataAdapter())
{
cmd.CommandText = query;
da.SelectCommand = cmd;
if (Parameters != null)
{
foreach (KeyValuePair<string, object> kvp in Parameters)
{
DbParameter parameter = cmd.createParameter();
parameter.ParameterName = kvp.Key;
parameter.Value = kvp.Value;
cmd.Parameters.Add(parameter);
}
}
conn.Open();
da.Fill(dt);
return dt;
}
}
}

To answer your question, you could create an enumeration of database types, pass it into Select, and then inside Select you could switch on the value, where each case contains the corresponding code.
(However, this looks like bad design to me, since this looks like a good opportunity to use polymorphism, at least some of which you should already get through ADO.NET. You could fill the gaps yourself.)

You may want to look into the DbProviderFactory approach
http://msdn.microsoft.com/en-us/library/wda6c36e(v=vs.110).aspx

Related

Return different types of Lists<> in Method (C#)

At the moment I have a Method for executing database calls which returns a DataTable which is then converted into a List<>. Since I am using this Method for different database calls I need to make it return any List<>. This is at the moment not possible since I get an error:
Cannot convert List<T> to List<object>
What return type should the function have if i want to return any list?
e.g. it could be that the result list is of the type:
List<MirrorDeployments>
or:
List<ProductionDeployments>
My Function
public List<T> Execute<T>(string strSql, List<T> list)
{
using (OracleConnection conn = new OracleConnection(cnnStr))
{
using (OracleCommand objCommand = new OracleCommand(strSql, conn))
{
objCommand.CommandType = CommandType.Text;
DataTable dt = new DataTable();
OracleDataAdapter adp = new OracleDataAdapter(objCommand);
conn.Open();
adp.Fill(dt);
if (dt != null)
{
list = ConvertToList(dt, list).ToList();
}
}
}
return list;
}
Assuming that ConvertToList returns an enumerable of object:
public List<T> Execute<T>(string strSql)
{
using (OracleConnection conn = new OracleConnection(cnnStr))
{
using (OracleCommand objCommand = new OracleCommand(strSql, conn))
{
objCommand.CommandType = CommandType.Text;
DataTable dt = new DataTable();
OracleDataAdapter adp = new OracleDataAdapter(objCommand);
conn.Open();
adp.Fill(dt);
if (dt != null)
{
return ConvertToList(dt).Cast<T>().ToList();
}
}
}
return new List<T>();
}
I have removed the parameter list because seems useless.
A better option is to convert ConvertToList in a generic method ConvertToList<T> which does what its name say.

Would executing the SqlCommand be completely moot/redundant, and slow things down?

Thanks to some tips and reminders here, I changed my code from this kludgy mess:
try
{
DataSet dsUsage = new DataSet();
SqlConnection conn = new SqlConnection("SERVER=PROSQL05;DATABASE=platypusdata;UID=duckbill;PWD=poisonToe42;Connection Timeout=0");
SqlDataAdapter da = new SqlDataAdapter();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = String.Format("Exec sp_ViewProductUsage_MappingRS '{0}', '{1}', '{2}'", mammal, dateBegin, dateEnd);
da.SelectCommand = cmd;
conn.Open();
da.Fill(dsUsage);
conn.Close();
DataTable dtUsage = dsUsage.Tables[0];
if (dtUsage.Rows.Count > 0)
{
foreach (DataRow productUsageByMonthDataRow in dtUsage.Rows)
{
. . .
...to this:
try
{
SqlDataAdapter da = new SqlDataAdapter();
DataSet dsUsage = new DataSet();
using (SqlConnection conn = new SqlConnection(UsageRptConstsAndUtils.PlatypusConnStr))
{
using (SqlCommand cmd = new SqlCommand("sp_ViewProductUsage_MappingRS", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#Unit", SqlDbType.VarChar).Value = _unit;
cmd.Parameters.Add("#BegDate", SqlDbType.DateTime).Value = dtBegin;
cmd.Parameters.Add("#EndDate", SqlDbType.DateTime).Value = dtEnd;
da.SelectCommand = cmd;
conn.Open();
//cmd.ExecuteReader(); <- Is this even necessary?
da.Fill(dsUsage);
}
}
DataTable dtUsage = dsUsage.Tables[0];
if (dtUsage.Rows.Count > 0)
{
// Populate the cells
foreach (DataRow productUsageByMonthDataRow in dtUsage.Rows)
{
. . .
Note that I have SqlCommand's ExecuteReader commented out in the new code because it seems unnecessary due to the SqlDataAdapter being provided the SqlCommand. It works fine. So: am I correct in assuming I can remove cmd.ExecuteReader() altogether? Is there any benefit in retaining it, or would that be totally redundant and create "busy work" for the process?
UPDATE
So, to pass an array of SqlParameter (to the ExecuteDataSet method in MethodMan's answer), I take it that I would first have to do something like:
SqlParameter sqlp = new SqlParameter();
sqlp.ParameterName = "Unit";
sqlp.Value = _unit;
cmd.Parameters.Add(sqlp);
...etc. (and then add them to an array - or, possibly better a generic list of SqlParameter).
UPDATE 2
I just ran into this for the first time: if you use MethodMan's example (which I do) and you use a parameterless query, you need to bypass the parameter-adding loop like so:
if (null != parameters)
{
foreach (var item in parameters)
{
cmd.Parameters.Add(item);
}
}
I would personally create a SqlDBHelper class and pass call the stored procedure using a method such as this
public static class SqlDBHelper
{
public static DataSet ExecuteDataSet(string sql, CommandType cmdType, params SqlParameter[] parameters)
{
using (DataSet ds = new DataSet())
using (SqlConnection connStr = new SqlConnection(ConfigurationManager.ConnectionStrings["DbConn"].ConnectionString))
using (SqlCommand cmd = new SqlCommand(sql, connStr))
{
cmd.CommandType = cmdType;
foreach (var item in parameters)
{
cmd.Parameters.Add(item);
}
try
{
cmd.Connection.Open();
new SqlDataAdapter(cmd).Fill(ds);
}
catch (SqlException ex)
{
//log to a file or write to Console for example
Console.WriteLine(ex.Message);
}
return ds;
}
}
}
If you want to return a DataTable then change the return type in the Method signature and call the following in the return statement below
public static DataTable ExecuteDataSet(string sql, CommandType cmdType, params SqlParameter[] parameters)
return ds.Tables[0];
Here is an example on how you would call the method
someDataTable = SqlDBHelper.ExecuteDataSet("sp_ViewProductUsage_MappingRS", CommandType.StoredProcedure,
new SqlParameter() { ParameterName = "#Unit", SqlDbType = SqlDbType.VarChar, Value = _unit },
new SqlParameter() { ParameterName = "#BegDate", SqlDbType = SqlDbType.DateTime, Value = dtBegin },
new SqlParameter() { ParameterName = "#EndDate", SqlDbType = SqlDbType.DateTime, Value = dtEnd }
);

Why does the DataTableReader lose its data when using MySqlDataAdapter?

I have the following method:
public DataTableReader Get<T>(string sql, T[] parameters, CommandType commandType = CommandType.Text)
{
DataTableReader result;
using (var connection = new MySqlConnection(_connectionString))
{
using (var command = new MySqlCommand())
{
command.CommandType = commandType;
command.CommandText = sql;
command.Connection = connection;
if (parameters != null)
{
command.Parameters.AddRange(parameters);
}
using (var adapter = new MySqlDataAdapter())
{
adapter.SelectCommand = command;
using (var dataTable = new DataTable())
{
adapter.Fill(dataTable);
result = dataTable.CreateDataReader();
} // result contains data here
} // result "loses" data here
}
}
return result;
}
However, when I get to the row that I've commented about losing the data, the DataTableReader is empty. If I put a breakpoint in the row above it (where I've commented that the result contains the data) result does indeed contain the results.
What's going on? It's almost like something is being passed as a reference.
Edit: I should probably note that I've got the same code to connect to a SQL Server where any instance of a MySQL specific class above is replaced by SqlCommand,SqlDataAdapter instead. This all seems to work.
As requested, here is the corresponding method for MSSql:
public virtual DataTableReader Get(string sql, SqlParameter[] parameters, CommandType commandType = CommandType.Text)
{
DataTableReader result;
using (var sqlConnection = new SqlConnection(_coreConnectionString))
{
using (var myCommand = new SqlCommand())
{
myCommand.CommandType = commandType;
myCommand.CommandText = sql;
myCommand.Connection = sqlConnection;
if (parameters != null)
{
myCommand.Parameters.AddRange(parameters);
}
using (var myAdapter = new SqlDataAdapter())
{
myAdapter.SelectCommand = myCommand;
using (var myDataTable = new DataTable())
{
myAdapter.Fill(myDataTable);
result = myDataTable.CreateDataReader();
}
}
}
}
return result;
}
I've updated the top method to return the DataReader a bit sooner:
public DataTableReader Get<T>(string sql, T[] parameters, CommandType commandType = CommandType.Text)
{
using (var connection = new MySqlConnection(_connectionString))
{
using (var command = new MySqlCommand())
{
command.CommandType = commandType;
command.CommandText = sql;
command.Connection = connection;
if (parameters != null)
{
command.Parameters.AddRange(parameters);
}
using (var adapter = new MySqlDataAdapter())
{
adapter.SelectCommand = command;
using (var dataTable = new DataTable())
{
adapter.Fill(dataTable);
var reader = dataTable.CreateDataReader();
return reader;
}
}
}
}
}
I've left the assignment of the variable on a different line to the return statement so I can verify that reader is being filled. However, when it gets returned to the calling method, there's nothing there.
The code that is calling Get() is var dt = _dbHelper.Get(sql, parameters) and I know that the sql works because before it is returned, there is the data I am expecting in the object.
More Edits:I've been doing some more digging as this is really annoying me. Firstly, if I use var reader = dataTable.Copy().CreateDataReader(); the data is returned. But of course then this creates a new version of the object, so this might cause a memory issue.
Secondly (and this really annoys me) the Fill() method that MySqlDataAdapter uses isn't its own implementation. It uses the implementation from DbDataAdapter (which both it and SqlDataAdapter inherits from). So how come it doesn't work the same?
In this line:
using (var myDataTable = new DataTable())
{
myAdapter.Fill(myDataTable);
result = myDataTable.CreateDataReader();
}
with the using you are doing that when the code goes out from the using, the DataTable is disposed and then yo uwill get empty data.
Try declaring the DataTable and closing it at the end. Maybe using a try/catch/finally block is a good way to do this, and in the finally you can add the dispose.
I hope this helps

Return Result from Select Query in stored procedure to a List

I'm writing a stored procedure that currently contains only a SELECT query. It will be expanded to do a number of other things, which is why it has to be a stored procedure, but for now, it is a simple query.
Something like this:
SELECT name, occupation, position
FROM jobs
WHERE ...
I'm looking to return the results of this query to be used in C#. I want to add it to a list so that I can bind it to a GridView component.
I don't know how to go about this, though. If I have to insert it into a list after returning all selected data, then that's alright, I just need to know how to properly return the data so that I can do that.
If I can return it in a format that can be popped right into a list, though, that would be ideal.
In stored procedure, you just need to write the select query like the below:
CREATE PROCEDURE TestProcedure
AS
BEGIN
SELECT ID, Name
FROM Test
END
On C# side, you can access using Reader, datatable, adapter.
Using adapter has just explained by Susanna Floora.
Using Reader:
SqlConnection connection = new SqlConnection(ConnectionString);
command = new SqlCommand("TestProcedure", connection);
command.CommandType = System.Data.CommandType.StoredProcedure;
connection.Open();
SqlDataReader reader = command.ExecuteReader();
List<Test> TestList = new List<Test>();
Test test = null;
while (reader.Read())
{
test = new Test();
test.ID = int.Parse(reader["ID"].ToString());
test.Name = reader["Name"].ToString();
TestList.Add(test);
}
gvGrid.DataSource = TestList;
gvGrid.DataBind();
Using dataTable:
SqlConnection connection = new SqlConnection(ConnectionString);
command = new SqlCommand("TestProcedure", connection);
command.CommandType = System.Data.CommandType.StoredProcedure;
connection.Open();
DataTable dt = new DataTable();
dt.Load(command.ExecuteReader());
gvGrid.DataSource = dt;
gvGrid.DataBind();
I hope it will help you. :)
SqlConnection connection = new SqlConnection(ConnectionString);
command = new SqlCommand("TestProcedure", connection);
command.CommandType = System.Data.CommandType.StoredProcedure;
connection.Open();
DataTable dt = new DataTable();
dt.Load(command.ExecuteReader());
gvGrid.DataSource = dt;
gvGrid.DataBind();
SqlConnection con = new SqlConnection("Data Source=DShp;Initial Catalog=abc;Integrated Security=True");
SqlDataAdapter da = new SqlDataAdapter("data", con);
da.SelectCommand.CommandType= CommandType.StoredProcedure;
DataSet ds=new DataSet();
da.Fill(ds, "data");
GridView1.DataSource = ds.Tables["data"];
GridView1.DataBind();
Passing Parameters in Stored Procedure and calling it in C# Code behind as shown below?
SqlConnection conn = new SqlConnection(func.internalConnection);
var cmd = new SqlCommand("usp_CustomerPortalOrderDetails", conn);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add("#CustomerId", SqlDbType.Int).Value = customerId;
cmd.Parameters.Add("#Qid", SqlDbType.VarChar).Value = qid;
conn.Open();
// Populate Production Panels
DataTable listCustomerJobDetails = new DataTable();
listCustomerJobDetails.Load(cmd.ExecuteReader());
conn.Close();
I had the same question, took me ages to find a simple solution.
Using ASP.NET MVC 5 and EF 6:
When you add a stored procedure to your .edmx model, the result of the stored procedure will be delivered via an auto-generated object called yourStoredProcName_result.
This _result object contains the attributes corresponding to the columns in the database that your stored procedure selected.
The _result class can be simply converted to a list:
yourStoredProcName_result.ToList()
// GET: api/GetStudent
public Response Get() {
return StoredProcedure.GetStudent();
}
public static Response GetStudent() {
using (var db = new dal()) {
var student = db.Database.SqlQuery<GetStudentVm>("GetStudent").ToList();
return new Response {
Sucess = true,
Message = student.Count() + " Student found",
Data = student
};
}
}
Building on some of the responds here, i'd like to add an alternative way. Creating a generic method using reflection, that can map any Stored Procedure response to a List. That is, a List of any type you wish, as long as the given type contains similarly named members to the Stored Procedure columns in the response.
Ideally, i'd probably use Dapper for this - but here goes:
private static SqlConnection getConnectionString() // Should be gotten from config in secure storage.
{
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
builder.DataSource = "it.hurts.when.IP";
builder.UserID = "someDBUser";
builder.Password = "someDBPassword";
builder.InitialCatalog = "someDB";
return new SqlConnection(builder.ConnectionString);
}
public static List<T> ExecuteSP<T>(string SPName, List<SqlParameter> Params)
{
try
{
DataTable dataTable = new DataTable();
using (SqlConnection Connection = getConnectionString())
{
// Open connection
Connection.Open();
// Create command from params / SP
SqlCommand cmd = new SqlCommand(SPName, Connection);
// Add parameters
cmd.Parameters.AddRange(Params.ToArray());
cmd.CommandType = CommandType.StoredProcedure;
// Make datatable for conversion
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dataTable);
da.Dispose();
// Close connection
Connection.Close();
}
// Convert to list of T
var retVal = ConvertToList<T>(dataTable);
return retVal;
}
catch (SqlException e)
{
Console.WriteLine("ConvertToList Exception: " + e.ToString());
return new List<T>();
}
}
/// <summary>
/// Converts datatable to List<someType> if possible.
/// </summary>
public static List<T> ConvertToList<T>(DataTable dt)
{
try // Necesarry unfotunately.
{
var columnNames = dt.Columns.Cast<DataColumn>()
.Select(c => c.ColumnName)
.ToList();
var properties = typeof(T).GetProperties();
return dt.AsEnumerable().Select(row =>
{
var objT = Activator.CreateInstance<T>();
foreach (var pro in properties)
{
if (columnNames.Contains(pro.Name))
{
if (row[pro.Name].GetType() == typeof(System.DBNull)) pro.SetValue(objT, null, null);
else pro.SetValue(objT, row[pro.Name], null);
}
}
return objT;
}).ToList();
}
catch (Exception e)
{
Console.WriteLine("Failed to write data to list. Often this occurs due to type errors (DBNull, nullables), changes in SP's used or wrongly formatted SP output.");
Console.WriteLine("ConvertToList Exception: " + e.ToString());
return new List<T>();
}
}
Gist: https://gist.github.com/Big-al/4c1ff3ed87b88570f8f6b62ee2216f9f
May be this will help:
Getting rows from DB:
public static DataRowCollection getAllUsers(string tableName)
{
DataSet set = new DataSet();
SqlCommand comm = new SqlCommand();
comm.Connection = DAL.DAL.conn;
comm.CommandType = CommandType.StoredProcedure;
comm.CommandText = "getAllUsers";
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = comm;
da.Fill(set,tableName);
DataRowCollection usersCollection = set.Tables[tableName].Rows;
return usersCollection;
}
Populating DataGridView from DataRowCollection :
public static void ShowAllUsers(DataGridView grdView,string table, params string[] fields)
{
DataRowCollection userSet = getAllUsers(table);
foreach (DataRow user in userSet)
{
grdView.Rows.Add(user[fields[0]],
user[fields[1]],
user[fields[2]],
user[fields[3]]);
}
}
Implementation :
BLL.BLL.ShowAllUsers(grdUsers,"eusers","eid","euname","eupassword","eposition");

Read SQL Table into C# DataTable

I've read a lot of posts about inserting a DataTable into a SQL table, but is there an easy way to pull a SQL table into a .NET DataTable?
Here, give this a shot (this is just a pseudocode)
using System;
using System.Data;
using System.Data.SqlClient;
public class PullDataTest
{
// your data table
private DataTable dataTable = new DataTable();
public PullDataTest()
{
}
// your method to pull data from database to datatable
public void PullData()
{
string connString = #"your connection string here";
string query = "select * from table";
SqlConnection conn = new SqlConnection(connString);
SqlCommand cmd = new SqlCommand(query, conn);
conn.Open();
// create data adapter
SqlDataAdapter da = new SqlDataAdapter(cmd);
// this will query your database and return the result to your datatable
da.Fill(dataTable);
conn.Close();
da.Dispose();
}
}
var table = new DataTable();
using (var da = new SqlDataAdapter("SELECT * FROM mytable", "connection string"))
{
da.Fill(table);
}
Lots of ways.
Use ADO.Net and use fill on the data adapter to get a DataTable:
using (SqlDataAdapter dataAdapter
= new SqlDataAdapter ("SELECT blah FROM blahblah ", sqlConn))
{
// create the DataSet
DataSet dataSet = new DataSet();
// fill the DataSet using our DataAdapter
dataAdapter.Fill (dataSet);
}
You can then get the data table out of the dataset.
Note in the upvoted answer dataset isn't used, (It appeared after my answer)
It does
// create data adapter
SqlDataAdapter da = new SqlDataAdapter(cmd);
// this will query your database and return the result to your datatable
da.Fill(dataTable);
Which is preferable to mine.
I would strongly recommend looking at entity framework though ... using datatables and datasets isn't a great idea. There is no type safety on them which means debugging can only be done at run time. With strongly typed collections (that you can get from using LINQ2SQL or entity framework) your life will be a lot easier.
Edit: Perhaps I wasn't clear: Datatables = good, datasets = evil. If you are using ADO.Net then you can use both of these technologies (EF, linq2sql, dapper, nhibernate, orm of the month) as they generally sit on top of ado.net. The advantage you get is that you can update your model far easier as your schema changes provided you have the right level of abstraction by levering code generation.
The ado.net adapter uses providers that expose the type info of the database, for instance by default it uses a sql server provider, you can also plug in - for instance - devart postgress provider and still get access to the type info which will then allow you to as above use your orm of choice (almost painlessly - there are a few quirks) - i believe Microsoft also provide an oracle provider. The ENTIRE purpose of this is to abstract away from the database implementation where possible.
Vendor independent version, solely relies on ADO.NET interfaces; 2 ways:
public DataTable Read1<T>(string query) where T : IDbConnection, new()
{
using (var conn = new T())
{
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = query;
cmd.Connection.ConnectionString = _connectionString;
cmd.Connection.Open();
var table = new DataTable();
table.Load(cmd.ExecuteReader());
return table;
}
}
}
public DataTable Read2<S, T>(string query) where S : IDbConnection, new()
where T : IDbDataAdapter, IDisposable, new()
{
using (var conn = new S())
{
using (var da = new T())
{
using (da.SelectCommand = conn.CreateCommand())
{
da.SelectCommand.CommandText = query;
da.SelectCommand.Connection.ConnectionString = _connectionString;
DataSet ds = new DataSet(); //conn is opened by dataadapter
da.Fill(ds);
return ds.Tables[0];
}
}
}
}
I did some performance testing, and the second approach always outperformed the first.
Stopwatch sw = Stopwatch.StartNew();
DataTable dt = null;
for (int i = 0; i < 100; i++)
{
dt = Read1<MySqlConnection>(query); // ~9800ms
dt = Read2<MySqlConnection, MySqlDataAdapter>(query); // ~2300ms
dt = Read1<SQLiteConnection>(query); // ~4000ms
dt = Read2<SQLiteConnection, SQLiteDataAdapter>(query); // ~2000ms
dt = Read1<SqlCeConnection>(query); // ~5700ms
dt = Read2<SqlCeConnection, SqlCeDataAdapter>(query); // ~5700ms
dt = Read1<SqlConnection>(query); // ~850ms
dt = Read2<SqlConnection, SqlDataAdapter>(query); // ~600ms
dt = Read1<VistaDBConnection>(query); // ~3900ms
dt = Read2<VistaDBConnection, VistaDBDataAdapter>(query); // ~3700ms
}
sw.Stop();
MessageBox.Show(sw.Elapsed.TotalMilliseconds.ToString());
Read1 looks better on eyes, but data adapter performs better (not to confuse that one db outperformed the other, the queries were all different). The difference between the two depended on query though. The reason could be that Load requires various constraints to be checked row by row from the documentation when adding rows (its a method on DataTable) while Fill is on DataAdapters which were designed just for that - fast creation of DataTables.
Centerlized Model: You can use it from any where!
You just need to call Below Format From your function to this class
DataSet ds = new DataSet();
SqlParameter[] p = new SqlParameter[1];
string Query = "Describe Query Information/either sp, text or TableDirect";
DbConnectionHelper dbh = new DbConnectionHelper ();
ds = dbh. DBConnection("Here you use your Table Name", p , string Query, CommandType.StoredProcedure);
That's it. it's perfect method.
public class DbConnectionHelper {
public DataSet DBConnection(string TableName, SqlParameter[] p, string Query, CommandType cmdText) {
string connString = # "your connection string here";
//Object Declaration
DataSet ds = new DataSet();
SqlConnection con = new SqlConnection();
SqlCommand cmd = new SqlCommand();
SqlDataAdapter sda = new SqlDataAdapter();
try {
//Get Connection string and Make Connection
con.ConnectionString = connString; //Get the Connection String
if (con.State == ConnectionState.Closed) {
con.Open(); //Connection Open
}
if (cmdText == CommandType.StoredProcedure) //Type : Stored Procedure
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = Query;
if (p.Length > 0) // If Any parameter is there means, we need to add.
{
for (int i = 0; i < p.Length; i++) {
cmd.Parameters.Add(p[i]);
}
}
}
if (cmdText == CommandType.Text) // Type : Text
{
cmd.CommandType = CommandType.Text;
cmd.CommandText = Query;
}
if (cmdText == CommandType.TableDirect) //Type: Table Direct
{
cmd.CommandType = CommandType.Text;
cmd.CommandText = Query;
}
cmd.Connection = con; //Get Connection in Command
sda.SelectCommand = cmd; // Select Command From Command to SqlDataAdaptor
sda.Fill(ds, TableName); // Execute Query and Get Result into DataSet
con.Close(); //Connection Close
} catch (Exception ex) {
throw ex; //Here you need to handle Exception
}
return ds;
}
}

Categories

Resources