Can't Insert Data into DataBase(SQL) using MVC - sql

This is my controller class
[HttpPost]
public ActionResult SignUp(SignupModel model)
{
User u = new User();
u.LoginId = model.LoginId;
u.Password = model.Password;
u.FullName = model.FullName;
new UsersHandler().AddUser(u);}
UserHandler class contains
public void AddUser(User user)
{
new DAC().Insert(user);
}
DAC class contains the connections and UsersDAC contains the queries
Insert Query
internal void Insert(User user)
{
List<SqlParameter> temp = new List<SqlParameter>
{
new SqlParameter("#FullName", user.FullName),
new SqlParameter("#LoginId", user.LoginId),
new SqlParameter("#Password", user.Password)
};
SqlConnection con = DACHelper.GetConnection();
using (con)
{
con.Open();
SqlTransaction t = con.BeginTransaction();
try
{
user.Id = (int)DACHelper.ExecuteScalar(INSERT, temp, t);
DACHelper.Execute(INSERT, temp);
t.Commit();
}
catch (Exception)
{
t.Rollback();
}
}
}
DACHelper.Execute(INSERT, temp);
It Executes but doesn't Insert any thing in table.
Stored Procedure
ALTER PROCEDURE [dbo].[Users_Insert]
#FullName varchar(50),
#LoginId varchar(50),
#Password varchar(50)
AS
Insert into [Users]
([FullName],[LoginId],[Password])
Values (#FullName,#LoginId,#Password)
Select ##IDENTITY from [Users]

My suggestions:
Test the stored procedure outside of your program using the same SQL credentials used by the program. If this works, the problem is your code.
Try calling the stored procedure by building the code without the use of your classes that hide some of what is being done.
Make sure that the SqlCommand object knows that it should be using a CommandType of CommandType.StoredProcedure.
Do not use SCOPE_IDENTITY or ##IDENTITY. The safest way to get the identity field is as follows (assume the field name is ID):
INSERT into [Users] ([FullName],[LoginID],[Password])
OUTPUT INSERTED.ID
VALUES (#FullName, #LoginID, #Password)
This will always be the correct value.

What about the commit mode? Is it in auto-commit mode. If not try to execute commit manually using the script. This should display message as transaction is committed.

You do not have used sqlparamater.appwithvalue may be this cause this issue..
internal void Insert(User user)
{
List<SqlParameter> temp = new List<SqlParameter>
{
new SqlParameter().AddWithvalue("#FullName", user.FullName),
new SqlParameter().AddWithvalue("#LoginId", user.LoginId),
new SqlParameter().AddWithvalue("#Password", user.Password)
};
SqlConnection con = DACHelper.GetConnection();
using (con)
{
con.Open();
SqlTransaction t = con.BeginTransaction();
try
{
user.Id = (int)DACHelper.ExecuteScalar(INSERT, temp, t);
DACHelper.Execute(INSERT, temp);
t.Commit();
}
catch (Exception)
{
t.Rollback();
}
}
}

internal void Insert(User user)
{
List<SqlParameter> temp = new List<SqlParameter>
{
new SqlParameter("#LoginId", user.LoginId),
new SqlParameter("#Password", user.Password),
new SqlParameter("#FullName", user.FullName),
};
SqlConnection con = DACHelper.GetConnection();
using (con)
{
con.Open();
SqlTransaction t = con.BeginTransaction();
user.Id = (Int32)DACHelper.ExecuteScalar(INSERT, temp, t);
t.Commit();
}
}
This will work by removing try/catch.

Related

How Can I call Store procedure and a table in the same function in .net core repository?

I am making an API using ASP.netCore to fetch data from teradata. I have 2 store procedure on Teradata DB one for encryption one for description. What I want to achieve is when user call the get method to fetch data, my Store procedure should run first and then it should return all table to user(changed as SP).
I have tried a lot but didn't manage to find any way to call store procedure and Select * table together. If I run the only store procedure OR call only select * table it work. I want to call both (SP and select*) so first SP should run and change the data then return the changed data table.
My codes are following.
Codes for GetDataTable
public IEnumerable<myTable> GetData(IConfiguration _configuration)
{
try
{
myTable TableReturn = new myTable();
List<myTable> dataReturn = new List<myTable>();
var connectionString = _configuration.GetConnectionString("TeradataConnectionString");
using (var connection = new TdConnection(connectionString))
{
'Date_Of_Birth', ENCRYPTEDSTRING);";
TdCommand cmd = new TdCommand("SELECT * FROM Project.myTable;", connection) ;
TdCommand Db = (TdCommand)cmd;
Db.Connection = connection;
connection.Open();
TdDataReader reader = Db.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
var newTable = new myTable();
newTable.Employee_Id = (string)reader.GetString(0);
newTable.First_name = (string)reader.GetString(1);
newTable.Last_Name = (string)reader.GetString(2);
newTable.Date_Of_Birth = (string)reader.GetString(3);
newTable.Phone = (string)reader.GetString(4);
newTable.Em_Position = (string)reader.GetString(5);
dataReturn.Add(newTable);
}
}
else
{
Console.WriteLine("no rows found");
}
}
return dataReturn;
}
catch (Exception e)
{
throw new Exception();
}
}
My codes for store procedure are following
public IEnumerable<DecryptedData> DecryptedData(IConfiguration _configuration)
{
// DecryptedData DecryptedReturn = new DecryptedData();
List<DecryptedData> dataReturn = new List<DecryptedData>();
var connectionString = _configuration.GetConnectionString("TeradataConnectionString");
using (var connection = new TdConnection(connectionString))
{
string command = "CALL Project.Decryption(STATUS,'Project' ,'myTable', 'Date_Of_Birth', ENCRYPTEDSTRING);";
TdCommand cmd = new TdCommand(command, connection);
TdCommand Db = (TdCommand)cmd;
Db.Connection = connection;
connection.Open();
TdDataReader reader = Db.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
var DecryptedData = new DecryptedData();
DecryptedData.Date_Of_Birth = reader.GetString(1);
dataReturn.Add(DecryptedData);
Console.WriteLine(dataReturn);
}
}
else
{
Console.WriteLine("no rows found");
}
}
return dataReturn;
}

Could not GetActiveTransaction

I need to call stored procedure in my App Service. I'm following this tutorial to create a custom repository. But I could not find the Context.Database.
Here is the code:
[UnitOfWork]
public virtual async Task<List<string>> GetUserNames()
{
EnsureConnectionOpen();
using (var command = CreateCommand("GetUsernames", CommandType.storedProcedure))
{
using (var dataReader = await command.ExecuteReaderAsync())
{
var result = new List<string>();
while (dataReader.Read())
{
result.Add(dataReader["UserName"].ToString());
}
return result;
}
}
}
What is the Context.Database and how do I use it?
My application is MVC in .Net4.6.1.
Update 1
I have resolved this issue by inheriting MyApplicationRepositoryBase.
Now I face a new issue when trying to GetActiveTransaction. I don't have any idea about this. What can I do?
Here is the code:
private DbTransaction GetActiveTransaction()
{
return (DbTransaction)_transactionProvider.GetActiveTransaction(new ActiveTransactionProviderArgs
{
{"ContextType", typeof(MyDbContext) },
{"MultiTenancySide", MultiTenancySide }
});
}
Here is the error log:
System.NullReferenceException: Object reference not set to an instance of an object.
at Abp.EntityFramework.EfActiveTransactionProvider.GetActiveTransaction(ActiveTransactionProviderArgs args) in D:\Github\aspnetboilerplate\src\Abp.EntityFramework\EntityFramework\EfActiveTransactionProvider.cs:line 21
Update 2
I tried to comment out the command.Transaction and it worked:
private DbCommand CreateCommand(string commandText, CommandType commandType, params SqlParameter[] parameters)
{
var command = Context.Database.GetDbConnection().CreateCommand();
command.CommandText = commandText;
command.CommandType = commandType;
// command.Transaction = GetActiveTransaction();
foreach (var parameter in parameters)
{
command.Parameters.Add(parameter);
}
return command;
}
I still need to put my code under a Transaction, so I don't want to comment out this line. What should I do?
Now I faced the new issue when trying to get Active Transaction
Add this in PreInitialize method of YourProjectNameDataModule:
Configuration.ReplaceService<IEfTransactionStrategy, DbContextEfTransactionStrategy>(DependencyLifeStyle.Transien‌​t);

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();

Loading data from SQL Server into C# application

I have some problem accessing my data from a SQL Server database via C# application. I have a small project to make and I can't go further because my data is loading in. I try to load it in a DataGridView.
Here are some code examples:
public List<Country> GetCountryList()
{
string query = "SELECT * FROM Orszag", error = string.Empty;
SqlDataReader rdr = ExecuteReader(query, ref error);
List<Country> countryList = new List<Country>();
if (error == "OK")
{
while (rdr.Read())
{
Country item = new Country();
item.CountryId = Convert.ToInt32(rdr[0]);
item.CountryName = rdr[1].ToString();
countryList.Add(item);
}
}
CloseDataReader(rdr);
return countryList;
}
This is where I put my data in a list
private void FillDgvGames()
{
dgvGames.Rows.Clear();
List<Country> CountryList = m_Country.GetCountryList();
foreach (Country item in CountryList)
{
dgvGames.Rows.Add(item.CountryId,item.CountryName);
}
}
And this is where I retrieve it ... I have to make the same thing with 8 more tables but this is the simplest and I thought it's easier this way.... if someone can help me I'd appreciate it ...
PS:
This is the execute reader
protected SqlDataReader ExecuteReader(string query, ref string errorMessage)
{
try
{
OpenConnection();
SqlCommand cmd = new SqlCommand(query, m_Connection);
SqlDataReader rdr = cmd.ExecuteReader();
errorMessage = "OK";
return rdr;
}
catch (SqlException e)
{
errorMessage = e.Message;
CloseConnection();
return null;
}
}
And this is the connection string
protected string m_ConnectionString = "Data Source=SpD-PC;Initial Catalog=master;Integrated Security=SSPI";
Are you setting the data source of your DataGridView?
dgvGames.DataSource = CountryList;

how to enable SQL Application Role via Entity Framework

I'm now developing big government application with entity framework. at first i have one problem about enable SQL application role. with ado.net I'm using below code:
SqlCommand cmd = new SqlCommand("sys.sp_setapprole");
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = _sqlConn;
SqlParameter paramAppRoleName = new SqlParameter();
paramAppRoleName.Direction = ParameterDirection.Input;
paramAppRoleName.ParameterName = "#rolename";
paramAppRoleName.Value = "AppRole";
cmd.Parameters.Add(paramAppRoleName);
SqlParameter paramAppRolePwd = new SqlParameter();
paramAppRolePwd.Direction = ParameterDirection.Input;
paramAppRolePwd.ParameterName = "#password";
paramAppRolePwd.Value = "123456";
cmd.Parameters.Add(paramAppRolePwd);
SqlParameter paramCreateCookie = new SqlParameter();
paramCreateCookie.Direction = ParameterDirection.Input;
paramCreateCookie.ParameterName = "#fCreateCookie";
paramCreateCookie.DbType = DbType.Boolean;
paramCreateCookie.Value = 1;
cmd.Parameters.Add(paramCreateCookie);
SqlParameter paramEncrypt = new SqlParameter();
paramEncrypt.Direction = ParameterDirection.Input;
paramEncrypt.ParameterName = "#encrypt";
paramEncrypt.Value = "none";
cmd.Parameters.Add(paramEncrypt);
SqlParameter paramEnableCookie = new SqlParameter();
paramEnableCookie.ParameterName = "#cookie";
paramEnableCookie.DbType = DbType.Binary;
paramEnableCookie.Direction = ParameterDirection.Output;
paramEnableCookie.Size = 1000;
cmd.Parameters.Add(paramEnableCookie);
try
{
cmd.ExecuteNonQuery();
SqlParameter outVal = cmd.Parameters["#cookie"];
// Store the enabled cookie so that approle can be disabled with the cookie.
_appRoleEnableCookie = (byte[]) outVal.Value;
}
catch (Exception ex)
{
result = false;
msg = "Could not execute enable approle proc." + Environment.NewLine + ex.Message;
}
But no matter how much I searched I could not find a way to implement on EF.
Another question is: how to Add Application Role to Entity data model designer?
I'm using the below code for execute parameter with EF:
AEntities ar = new AEntities();
DbConnection con = ar.Connection;
con.Open();
msg = "";
bool result = true;
DbCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = con;
var d = new DbParameter[]{
new SqlParameter{ ParameterName="#r", Value ="AppRole",Direction = ParameterDirection.Input}
, new SqlParameter{ ParameterName="#p", Value ="123456",Direction = ParameterDirection.Input}
};
string sql = "EXEC " + procName + " #rolename=#r,#password=#p";
var s = ar.ExecuteStoreCommand(sql, d);
When run ExecuteStoreCommand this line return error:
Application roles can only be activated at the ad hoc level.
I do it the following way (assuming Database First):
I create the DbContext from the db and call it MyEntitiesBase
I inherit from MyEntitiesBase to create MyEntities with the following code:
public partial class MyEntities : MyEntitiesBase
{
private byte[] appRoleCookie;
private void SetAppRole()
{
try
{
appRoleCookie = Database.SqlQuery<byte[]>(
#"
DECLARE #cookie VARBINARY(8000)
DECLARE #r INT
EXEC sp_setapprole 'user', 'pass', #fCreateCookie = true, #cookie = #cookie OUTPUT
SELECT #cookie").First();
}
catch
{
throw new AuthenticationException();
}
}
private void UnSetAppRole()
{
bool failed = Database.SqlQuery<bool>("DECLARE #result BIT; EXEC #result = sp_unsetapprole #cookie = " + appRoleCookie.ToHexadecimalString() + "; SELECT #result").First();
if (failed)
throw new SecurityException();
}
public MyEntities() : base()
{
Database.Connection.Open();
SetAppRole();
}
private bool disposed = false;
protected override void Dispose(bool disposing)
{
if (disposed)
return;
UnSetAppRole();
Database.Connection.Close();
disposed = true;
base.Dispose(disposing);
}
}
Where ToHexadecimalString is an extension method for IEnumerable<byte>, as follows:
public static class BytesExtensions
{
public static string ToHexadecimalString(this IEnumerable<byte> bytes)
{
return "0x" + string.Concat(bytes.Select(b => b.ToString("X2")));
}
}
And that's it. Works with connection pooling on and everything. You just use this inherited version instead of the one generated by EF.
Basically what you are doing is calling a stored procedure.
Entity Framework has functionality to excute stored procedures. Here is an explaination with a video: http://msdn.microsoft.com/en-us/data/gg699321.aspx
If your scrol down to the section "Using Import Functions to Map Stored Procedures" you will find the part that is relevant for you.