C# access to SQL Server database stored procedures and views - c#

In my C# application I need access to a SQL Server database. But only to some views and some stored procedures. Is it advisable to use Entity Framework? Or are there some lightweight methods to get access?

Is it advisable to use entityframework?
Yes it is.
Or ore there some lightweight methods to get access?
That is what Entity Framework is i believe.
Entity Framework + LINQ to SQL = Magic.

ADO.NET is much faster than EF and there is no difficulty
using (SqlConnection conn = new SqlConnection("Data Source=.; Initial Catalog=DBNAME; Integrated Security=true;"))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand("SELECT ID, NAME FROM VIEWNAME where id > 4550;", conn))
{
// cmd.CommandType = CommandType.StoredProcedure // for SP
using (SqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
dictionary.Add(dr.GetInt32(0), dr.GetString(1));
}
}
}
}
Connection string better store in app.config

Related

Is this Sql injection proof Asp.net code?

Can somebody tell me the pros and cons of this code? I know I can use stored procedures instead, but would it be easy to SQL inject this code considering I had a textbox where admins could input the commentid?
string commentId = a.Text;
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ForumDatabaseConnectionString"].ConnectionString);
con.Open();
string sql = "DELETE FROM Comment WHERE Comment.commentId = #commentid";
SqlCommand cmd = new SqlCommand(sql, con);
cmd.Parameters.AddWithValue("#commentid", commentId);
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
Yes, it looks fine, since you're using paramterized sql. However, you haven't given your table an alias, so I thing your sql should be
DELETE FROM Comment WHERE commentId = #commentid
As well as protecting you from sql injection attacks, Sql Server will know that this sql may be called again with different parameters, so can cache an efficient execution plan for it.
As an aside, you should always dispose of connections after using them.
string commentId = a.Text;
using (SqlConnection con = new SqlConnection(ConfigurationManager
.ConnectionStrings["ForumDatabaseConnectionString"].ConnectionString))
{
con.Open();
string sql = "DELETE FROM Comment WHERE Comment.commentId = #commentid";
using(SqlCommand cmd = new SqlCommand(sql, con))
{
cmd.Parameters.AddWithValue("#commentid", commentId);
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
}
As you can see, there is a fair amount of code for such a simple operation. You may wish to take a look at dapper, which will remove a lot of these issues. There are many libraries to help you, which are off-topic here, but its a lightweight, popular one
Pros:
Good thing is you are using parameters for command which is sql injection safe.
Cons:
Not well written.
Not using function for CRUD. Always Use functions to do CRUD operation.
No Use of Using block. Always use using block, so you don't need to dispose connection & command. You don't need to manually close it.
Use following code in DataAccessLayer.
public void DeleteComment(int commentId)
{
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ForumDatabaseConnectionString"].ConnectionString))
{
con.Open();
string sql = "DELETE FROM Comment WHERE Comment.commentId = #commentid";
using (SqlCommand cmd = new SqlCommand(sql, con))
{
cmd.Parameters.AddWithValue("#commentid", commentId);
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
}
}
You can write connection open code in separate function too.
Check this article for more detail:
https://www.codeproject.com/Articles/813965/Preventing-SQL-Injection-Attack-ASP-NET-Part-I

Dynamically choose SQL Server or Oracle database

I have an application that allows my user to run queries against a database of their choice. The database can be either SQL server or Oracle. this method accepts two parameters from another class, first parameter is the connection string to the database the user chooses, and the second is the database type. that part works fine. what I am trying to do is cut back on the code I need to write and not type the query and connection stuff over and over. so, I would like to do something like this. Obviously this wont work, but I'm open to most solutions.
public void createTable(string connectstring, string rdbms)
{
if (rdbms == "oracle")
{
con = new OracleConnection(connectionString);
con.Open();
OracleCommand query = con.CreateCommand();
}
else if (rdbms == "SQL Server")
{
con = new SqlConnection(connectionString);
con.Open();
SqlCommand query = con.CreateCommand();
}
else
{
// broke
}
query.CommandText = "CREATE TABLE " + RndName +
" (Col0 Varchar(10),Col1 Varchar(10), Col2 Varchar(10))";
query.ExecuteNonQuery();
con.Close();
executeInsertTransactions(connectstring);
}
This problem is generally solved via interfaces. There may be these common interfaces:
IConnection
IDataProvider
IRepository
Implement interfaces using MySql database, such as class MySqlConnection : IConnection. For Oracle, add class MsOracleConnection : IConnection.
Ideally you should abstract all the functionality into common interfaces. You will have to provide implementations for each database/storage engine you want to support. At runtime, you will use IoC container and DI principle to set up the current implementation. All the child dependencies will use interfaces passed in as parameters to constructor (or properties or methods)
You can create more abstract code by leveraging the framework's DbProviderFactory and using the obtained Db* classes.
Dim con As System.Data.IDbConnection
Dim cmd As System.Data.IDbCommand
Select Case ConDBType
Case TypeDatabase.SqlServer
con = New OleDbConnection(CN.ConnectionString)
cmd = New OleDbCommand
Case TypeDatabase.MySql
con = New MySqlConnection(CNMySql.ConnectionString)
cmd = New MySqlCommand
Case TypeDatabase.Access
Call InitNameing()
ConDBAccess.DataSource = PreparToRootNameing() & "\T" & NAME_SYSTEMDB
con = New OleDbConnection(CN.ConnectionString)
cmd = New OleDbCommand
End Select
cmd.Connection = con
con.Open()
cmd.CommandText = SQLUpdate
cmd.ExecuteNonQuery()

How to store image to sql database using Data Access Layer (asp.net)

I have a Data Access Layer
public void AddPartyAsIndividual(AddAnIndividual Student)
{
using (SqlConnection con = new SqlConnection(ConnString))
{
SqlCommand cmd = new SqlCommand("AddIndividualParty", con);
cmd.CommandType = CommandType.StoredProcedure;
md.Parameters.AddWithValue("#Student_Image", STudent.StudentImage);
if (con.State == ConnectionState.Closed)
{
con.Open();
cmd.ExecuteNonQuery();
}
}
Take a look at the following Codeproject article. It demonstrates how to store and retrieve images via SQL Server. The example used is a Winforms client, but the code can be adapted to any project type.
Storing and Retrieving Images from SQL Server Using Strored Procedures and C#.net

How to add/edit/retrieve data using Local Database file in Microsoft Visual Studio 2012

I want to get into developing applications that use databases. I am fairly experienced (as an amateur) at web based database utilization (mysql, pdo, mssql with php and old style asp) so my SQL knowledge is fairly good.
Things I have done already..
Create forms application
Add four text boxes (first name, last name, email, phone)
Added a datagrid control
Created a database connection using 'Microsoft SQL Server Database File (SqlClient)'
Created a table with fields corresponding to the four text boxes.
What I want to be able to do now is, when a button is clicked, the contents of the four edit boxes are inserted using SQL. I don't want to use any 'wrapper' code that hides the SQL from me. I want to use my experience with SQL as much as possible.
So I guess what I am asking is how do I now write the necessary code to run an SQL query to insert that data. I don't need to know the SQL code obviously, just the c# code to use the 'local database file' connection to run the SQL query.
An aside question might be - is there a better/simpler way of doing this than using the 'Microsoft SQL Server Database File' connection type (I have used it because it looks like it's a way to do it without having to set up an entire sql server)
The below is inserting data using parameters which I believe is a better approach:
var insertSQL = "INSERT INTO yourTable (firstName, lastName, email, phone) VALUES (firstName, lastName, email, phone)";
string connectionString = "Data Source=myServerAddress;Initial Catalog=myDataBase;Integrated Security=SSPI; User ID=userid;Password=pwd;"
using (var cn = new SqlCeConnection(connectionString))
using (var cmd = new SqlCeCommand(insertSQL, cn))
{
cn.Open();
cmd.Parameters.Add("firstName", SqlDbType.NVarChar);
cmd.Parameters.Add("lastName", SqlDbType.NVarChar);
cmd.Parameters.Add("email", SqlDbType.NVarChar);
cmd.Parameters.Add("phone", SqlDbType.NVarChar);
cmd.Parameters["firstName"].Value = firstName;
cmd.Parameters["lastName"].Value = lastName;
cmd.Parameters["email"].Value = email;
cmd.Parameters["phone"].Value = phone;
cmd.ExecuteNonQuery();
}
This is selecting data from database and populating datagridview:
var dt = new DataTable();
string connectionString = "Data Source=myServerAddress;Initial Catalog=myDataBase;Integrated Security=SSPI; User ID=userid;Password=pwd;"
using (var cn = new SqlCeConnection(connectionString )
using (var cmd = new SqlCeCommand("Select * From yourTable", cn))
{
cn.Open();
using (var reader = cmd.ExecuteReader())
{
dt.Load(reader);
//resize the DataGridView columns to fit the newly loaded content.
yourDataGridView.AutoSize = true; yourDataGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
//bind the data to the grid
yourDataGridView.DataSource = dt;
}
}
This first example is an over view based upon how I think it will be easier to understand but this is not a recommended approach due to vulnerability to SQL injection (a better approach further down). However, I feel it is easier to understand.
private void InsertToSql(string wordToInsert)
{
string connectionString = Data Source=myServerAddress;Initial Catalog=myDataBase;Integrated Security=SSPI; User ID=myDomain\myUsername;Password=myPassword;
string queryString = "INSERT INTO table_name (column1) VALUES (" + wordToInsert + ")"; //update as you feel fit of course for insert/update etc
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open()
SqlDataAdapter adapter = new SqlDataAdapter();
SqlCommand command = new SqlCommand(queryString, connection);
command.ExecuteNonQuery();
connection.Close();
}
}
I would also suggest wrapping it in a try/catch block to ensure the connection closes if it errors.
I am not able to test this but I think it is OK!
Again don't do the above in live as it allows SQL injection - use parameters instead. However, it may be argued it is easier to do the above if you come from PHP background (just to get comfortable).
This uses parameters:
public void Insert(string customerName)
{
try
{
string connectionString = Data Source=myServerAddress;Initial Catalog=myDataBase;Integrated Security=SSPI; User ID=myDomain\myUsername;Password=myPassword;
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
connection.Open() SqlCommand command = new SqlCommand( "INSERT INTO Customers (CustomerName" + "VALUES (#Name)", connection);
command.Parameters.Add("#Name", SqlDbType.NChar, 50, " + customerName +");
command.ExecuteNonQuery();
connection.Close();
}
catch()
{
//Logic in here
}
finally()
{
if(con.State == ConnectionState.Open)
{
connection.Close();
}
}
}
And then you just change the SQL string to select or add!

TelerikRadGrid how to insert,update and delete into SQL database

I am using Telerik controls in Visual Studio 2008, in RadGrid. I create a PopUp windows includes all the TextBoxes and controls that I need to use in database but how can I declare a function in order to insert, update and delete ? And where!?
You can use Data Access Layer for Definition of the the function to send the request to database
If you want to use SQL Server. Following is the code.
using (System.Data.SqlClient.SqlConnection con = new SqlConnection("YourConnection string")) {
con.Open();
SqlCommand cmd = new SqlCommand();
string expression = "Parameter value";
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "Your Stored Procedure";
cmd.Parameters.Add("Your Parameter Name",
SqlDbType.VarChar).Value = expression;
cmd.Connection = con;
using (IDataReader dr = cmd.ExecuteReader())
{
if (dr.Read())
{
}
}
}
You can also use Microsoft Enterprise Library
You can Use Business Logic Layer to call the database layer function and also can perform validations before sending the data to Presentation Layer
Finally, You can call the Business Logic Layer objects in your Presentation layer

Categories