How to convert SQL to LINQ? - sql

Here is my IsValid user login code in MVC4 model.
I'm trying to have my SQL command convert to LINQ.
How can I convert it to LINQ way?
public bool IsValid(string _username, string _password)
{
using (var cn = new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename" +
#"='C:\Tutorials\1 - Creating a custom user login form\Creating " +
#"a custom user login form\App_Data\Database1.mdf';Integrated Security=True"))
{
string _sql = #"SELECT [Username] FROM [dbo].[System_Users] " +
#"WHERE [Username] = #u AND [Password] = #p";
var cmd = new SqlCommand(_sql, cn);
cmd.Parameters
.Add(new SqlParameter("#u", SqlDbType.NVarChar))
.Value = _username;
cmd.Parameters
.Add(new SqlParameter("#p", SqlDbType.NVarChar))
.Value = Helpers.SHA1.Encode(_password);
cn.Open();
var reader = cmd.ExecuteReader();
if (reader.HasRows)
{
reader.Dispose();
cmd.Dispose();
return true;
}
else
{
reader.Dispose();
cmd.Dispose();
return false;
}
}
}

After you've LINQ or any ORM setup for your application, it can be converted to simple LINQ statement.
return _dbContext.Users.Any(c=>c.UserName == _username && c.Password == Helpers.SHA1.Encode(_password));

I would first look at using an Entity Data Model like the ones in Entity Framework (http://msdn.microsoft.com/en-gb/data/ef.aspx) to model your database objects in C# and add one to your project.
Then I would create a Stored Procedure in your DB to handle the execution of the SQL statement, passing in the parameters you want to test against.
Then, I would import the stored procedure into the Data Model and run a LINQ query against it.
Something along the lines of:
var valid = (from users in context.CheckUserMembership(userName: userName, password: password)
select new User
{
UserId = users.UserId,
UserName = users.Username
}).Count() > 0;
Where context is a reference to the Data Context generated by the Entity Data Model wizard and CheckUserMembership is the imported stored procedure containing your SQL statement.

Related

Must declare the scalar variable "#employeeid" in stored procedure insert in ASP.NET MVC 5

I want to insert data into a database using a stored procedure, Entity Framework in ASP.NET MVC 5. It works in SQL Server, but when I execute the procedure but in Visual Studio while inserting, I get that error.
My controller code is:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SaveEntitlement(Entitlement entment)
{
if (!ModelState.IsValid)
{
var viewmodel = new EntitlementViewModel(entment);
return View("EntitlementIndex", viewmodel);
}
if (entment.EntitlementId == 0)
{
var courseList = _dbContext.Entitlement.SqlQuery ("exec APPLIEDDAYS #employeeid,#LeaveTypeId,#LeavePeriodId,#startdate,#enddate", entment.EmployeeId,entment.LeaveTypeId,entment.LeavePeriodId,entment.FromDate.ToShortDateString(),entment.UptoDate.ToShortDateString()).ToList<Entitlement>();
////_dbContext.Entitlement.Add(entment);
_dbContext.SaveChanges();
TempData["msg"] = "Record Saved Successfully!";
}
return RedirectToAction("EntitlementIndex", "LeaveSetup");
}
Error is:
I believe that happens when one of the parameters you are using (employeeid in this case) is null, not "null" as in string. Before calling the procedure you can assign proper values to your parameters.
So assuming entment.EmployeeId is a type of int?:
if (entment.EntitlementId == 0)
{
var param1 = !entment.EmployeeId.HasValue ? "null" : entment.EmployeeId.ToString();
var courseList = _dbContext.Entitlement.SqlQuery ("exec APPLIEDDAYS #employeeid,#LeaveTypeId,#LeavePeriodId,#startdate,#enddate",
param1,entment.LeaveTypeId,entment.LeavePeriodId,entment.FromDate.ToShortDateString(),entment.UptoDate.ToShortDateString()).ToList<Entitlement>();
////_dbContext.Entitlement.Add(entment);
_dbContext.SaveChanges();
TempData["msg"] = "Record Saved Successfully!";
}
PS: Not sure if this is the right way to do it but it should work.
I think you should declare parameters for each parameter in your stored procedure like below:
SqlParameter param1 = new SqlParameter("#employeeid", entment.EmployeeId);
SqlParameter param2 = new SqlParameter("#LeaveTypeId", entment.LeaveTypeId);
SqlParameter param3 = new SqlParameter("#LeavePeriodId", entment.LeavePeriodId);
SqlParameter param4 = new SqlParameter("#startdate", entment.FromDate);
SqlParameter param5 = new SqlParameter("#enddate", entment.UptoDate);
and then
var courseList = _dbContext.Entitlement.SqlQuery ("exec APPLIEDDAYS #employeeid,#LeaveTypeId,#LeavePeriodId,#startdate,#enddate", param1, param2, param3, param4, param5).ToList<Entitlement>();
You should use Entitlement in front of SqlQuery not ToList()
var courseList = _dbContext.Entitlement.SqlQuery<Entitlement>("sql").ToList()
This is better that you use db.Database.SqlQueryRaw
using (var db = new _dbContext())
return db.Database.SqlQueryRaw<Entitlement>($"select top 1 username from tbl_people where id = '{userID}'").ToList().FirstOrDefault();

SQL Data Reader into Label - Value doesn't display

DB-Acess.cs
This is where the Public SqlDataReader getEmail is initialised.
public SqlDataReader getEmail(string UserName)
{
if (conn.State.ToString() == "Closed")
{
conn.Open();
}
//string noemail ="noemailsaved";
SqlCommand newCmd = conn.CreateCommand();
newCmd.Connection = conn;
newCmd.CommandType = CommandType.Text;
newCmd.CommandText = "Select Email from dbo.EMPLOYEE where Username ='" + UserName + "'";
SqlDataReader reader = newCmd.ExecuteReader();
while (reader.Read())
{
string email = reader["EMPLOYEE.Email"].ToString();
}
conn.Close();
reader.Close();
return reader;
}
I'm using OOP and calling the function in asp.net page and want to display the value in a label. Below is the code I'm using to call the function.
SqlDataReader reader = dba.getEmail(pname);
lblEmail.Text = reader.ToString();
lblEmail.DataBind();
Instead of seeing the Email address of the Employee i'm seeing System.Data.SqlClient.SqlDataReader
Please help in correcting this error.
Thank you in advance.
So there are so many issues going on, I decided to write this comment as the beginning to an appropriate solution.
First your method is called getEmail -- shouldn't it return the email (in other words, a string instead).
public string GetEmail(string UserName)
{
string email = string.Empty;
if (conn.State.ToString() == "Closed")
{
conn.Open();
}
//string noemail ="noemailsaved";
SqlCommand newCmd = conn.CreateCommand();
newCmd.Connection = conn;
newCmd.CommandType = CommandType.Text;
newCmd.CommandText = "Select Email from dbo.EMPLOYEE where Username ='" + UserName + "'";
SqlDataReader reader = newCmd.ExecuteReader();
while (reader.Read())
{
email = reader["EMPLOYEE.Email"].ToString();
}
conn.Close();
reader.Close();
return email;
}
Then all you have to do is:
lblEmail.Text = db.GetEmail(pname);
That should at least get you going. You should also look into using parameterized queries as well as the using statement.
Why do we always prefer using parameters in SQL statements?
There are a few things going wrong here:
1) You are setting the string email to the value of the reader. Which because you are declaring it inside the reader, will never be able to be used. You will lose scope immediately.
2) You are doing this:
lblEmail.Text = reader.ToString();
lblEmail.DataBind();
This is setting the label to the name of the reader (the instance), not the value the reader is producing. No reason to bind, either.
A better way to do it is
lblEmail.Text = email;
Make sure you declare the email variable outside the reader
ERRORS
Return type of the function getEmail is SqlDataReader and you are expecting String i.e. an Email.
Declaration of email in string email = reader["EMPLOYEE.Email"].ToString(); is inside while loop. Therefore, email becomes local to the while loop. It will not recognize outside the loop.
And you are returning reader' an instance ofSqlDataReader,but you were expecting aString`.
In you second code block, what your doing is not wrong(it won't give error) but that is not what you are expecting to get. You should be declaring a String variable eg. email and assign the function to it(or you can directly assign it to lblEmail Text property.
SUGGESTION
The way you are checking ConnectionState in if(conn.State.ToString() == "Closed") may give you the desired result but is not recommended. Instead you should check like this if (conn.State == ConnectionState.Closed).
Now the most awaiting part: The improvised code: lol!
UPDATE
public string getEmail(string UserName){
if (conn.State == ConnectionState.Closed){
conn.Open();
}
//string noemail ="noemailsaved";
string email="";
using(SqlCommand newCmd = new SqlCommand()){
newCmd.Connection = conn;
newCmd.CommandType = CommandType.Text;
newCmd.CommandText = "Select Email From dbo.EMPLOYEE Where Username = #uname";
newCmd.Parameters.AddWithValue("#uname",UserName);
using(SqlDataReader reader = newCmd.ExecuteReader()){
while (reader.Read()){
email = reader["Email"].ToString();
}
}
}
conn.Close();
//reader.Close();
return email ;
}
For setting the Label Text
lblEmail.Text = dba.getEmail(pname);
Yes that's cause you are calling ToString() on reader object and thus it just printing the classname fully qualified reader.ToString().
Moreover, you are dong it wrong. Current code shouldn't work since you are returning reader which has already been closed and thus you can't read from it. Rather, you should change your method to return the email and use it like
public string getEmail(string UserName)
{
if (conn.State.ToString() == "Closed")
{
conn.Open();
}
//string noemail ="noemailsaved";
SqlCommand newCmd = conn.CreateCommand();
newCmd.Connection = conn;
newCmd.CommandType = CommandType.Text;
// Hopefully your query returns a single email record
newCmd.CommandText = "Select Email from dbo.EMPLOYEE where Username ='" + UserName + "'";
SqlDataReader reader = newCmd.ExecuteReader();
string email = string.Empty;
while (reader.Read())
{
email = reader["EMPLOYEE.Email"].ToString();
}
conn.Close();
reader.Close();
return email;
}
Moreover if your query returns a single email value then use ExecuteScalar() rather like
string email = newCmd.ExecuteScalar() as string;
Now you can assign it in caller
lblEmail.Text = dba.getEmail(pname);
string q,d;
int ano=0;
SqlConnection con = new SqlConnection("Data Source=SANDEESQLEXPRESS;Initial Catalog=agent demo;Integrated Security=True");
con.Open();
SqlCommand cmd = new SqlCommand("select * from po where agentno=#ano", con);
cmd.Parameters.AddWithValue("ano",ano);
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read())
{
d = dr["date1"].ToString();
}
dr.Close();
Label1.Text = d+ "";
does not show value of date in lablel

How to use a Oracle database in ASP.NET without Entity Framework?

Can someone tell me in a simple way, how can I use an Oracle DB in my ASP.NET MVC 5 project? I have tried different articles but I didn't get a clear answer...
I think this is the simple way to do this:
using System.Data.OracleClient;
public string GetConnectionString()
{
String connString = "SERVER=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=YourHostName)(PORT=YourPort))(CONNECT_DATA=(SERVICE_NAME=YourServiceName)));uid=YourUserId;pwd=YourPassword;";
return connString;
}
public void ConnectingToOracle()
{
string connectionString = GetConnectionString();
using (OracleConnection connection = new OracleConnection())
{
connection.ConnectionString = connectionString;
connection.Open();
OracleCommand command = connection.CreateCommand();
string sql = "select * from MyDatabase where name like '%John Paul%'";
command.CommandText = sql;
OracleDataReader reader = command.ExecuteReader();
while (reader.Read())
{
string myField = (string)reader["address"]; //Get the address of John Paul
}
}
}

Stored Procedure in Orchard

Hi We are working on a project and i am trying to call a stored procedure. I have searched for the solution but i didn't find any way that how to call a stored procedure so can any one please tell me how to execute stored procedure.
How ever finally i am using the below code to execute the stored procedure and get the result.
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Suppress))
{
// temporary scope for new connection and setting stored procedure, parameters, and return RecordName list
using (SqlConnection cn = new SqlConnection(_settingsManager.LoadSettings().First().DataConnectionString))
{
if (cn.State == ConnectionState.Closed)
{
cn.Open();
}
const string storedProcedure = "usp_spName";
SqlCommand cmd = new SqlCommand(storedProcedure, cn);
cmd.Parameters.AddWithValue("#IsVerified", "value");
cmd.Parameters.AddWithValue("#page", "value");
// for out put parameter
cmd.Parameters.AddWithValue("#totalRows", 0);
cmd.Parameters["#totalRows"].Direction = ParameterDirection.Output;
cmd.CommandType = CommandType.StoredProcedure;
IDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
// To Get The Values of the result
int id=Convert.ToInt32(reader["Id"].ToString());
}
reader.Close();
try
{
// To Get the Out Put Perameter
totalRecords = (int)cmd.Parameters["#totalRows"].Value;
}
catch
{
totalRecords = 0;
}
cmd.Parameters.Clear();
cmd.Dispose();
cn.Close();
}
}
actually, I don't know about stored procedures, but you can call stored functions using code like examaple below. I'm new to C# and orchard, so may be my approach is not correct and good enough. At first you should get ISessionLocator object instance, using IOrchardServices, then create NHibernate ISession instance and then IQuery/ISQLQuery with CreateSQLQuery().
here is example code of Services class
public class ExampleService {
private readonly IOrchardServices _oServices;
public EParamsServices(IOrchardServices oServices) {
_oServices = oServices;
}
public float GetRegionPopulationDencity(int rId){
//resolve ISession locator (you can do this using dependencies in ctor)
ISessionLocator sl = _oServices.WorkContext.Resolve<ISessionLocator>();
//create session
ISession _session = sl.For(null);
// create raw SQL query
return _session.CreateSQLQuery(#"SELECT data.RegionDencity(:rId) as result")
.AddScalar("result", NHibernateUtil.Single)
.SetParameter<int>("rId", rId)
.List<float>()
.FirstOrDefault<float>();
}
}
I think you can exec stored procs the same way, just change SQL code do exec yourProcName and ExecuteUpdate() instead of List() method (I'm not sure in this part)
you also should add reference to NHibernate assembly to your project and add NHibernate & Orchard.Data to your using part.
You have to reference NHibernate and System.Data in your module , then you can use the below code
var cmd = _transactionManager.GetSession().Connection.CreateCommand();
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.CommandText = "MyStoredProcedure";
_transactionManager.GetSession().Transaction.Enlist(cmd);
cmd.ExecuteNonQuery();

Retrieve SQL Statement Does Not Go Into While Loop

I am having problem when doing retrieve function in 3-tier in C#. Here is the codes:
public DistributionStandardPackingUnits getSPUDetail(string distributionID)
{
DistributionStandardPackingUnits SPUFound = new DistributionStandardPackingUnits();
using (var connection = new SqlConnection(FoodBankDB.connectionString))
{
SqlCommand command = new SqlCommand("SELECT name, description, quantity FROM dbo.DistributionStandardPackingUnits WHERE distribution = '" + distributionID + "'", connection);
connection.Open();
using (var dr = command.ExecuteReader())
{
while (dr.Read())
{
string name = dr["name"].ToString();
string description = dr["description"].ToString();
string quantity = dr["quantity"].ToString();
SPUFound = new DistributionStandardPackingUnits(name, description, quantity);
}
}
}
return SPUFound;
}
When I run in browser, it just won't show up any retrieved data. When I run in debugging mode, I realized that when it hits the while loop, instead of executing the dr.Read(), it simply just skip the entire while loop and return null values. I wonder what problem has caused this. I tested my query using the test query, it returns me something that I wanted so I think the problem does not lies at the Sql statement.
Thanks in advance.
Edited Portion
public static SqlDataReader executeReader(string query)
{
SqlDataReader result = null;
System.Diagnostics.Debug.WriteLine("FoodBankDB executeReader: " + query);
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand(query, connection);
connection.Open();
result = command.ExecuteReader();
connection.Close();
return result;
}