How to execute stored procedure in EF7 beta8? - asp.net

I'm trying to run stored procedure in EF7 beta8 to return me a specific data. I'm trying to do it via FromSQL command, but not sure if this is right command.
strSQL = wt.DataSource.StoredProc;
foreach (var p in prms)
{
strSQL = strSQL + " #" + p.Name + " = '" + p.Value + "',";
}
strSQL = strSQL.Remove(strSQL.Length - 1); //removes last comma
var test = _dbContext.Widgets.FromSql("EXEC " + strSQL).ToList();
var test2 = _dbContext.Widgets.FromSql("SELECT * FROM Widgets").ToList();
Where test 2 works and returns data correctly, test1 is returning error:
The required column 'Id' was not present in the results of a 'FromSql' operation.
I'm assuming that the data I'm returning is not part of the model. If that's the case, how can I execute stored procedure and return the raw data to List or to DataTable?
EDIT:
I'm trying with SQLCommand:
var connection = (SqlConnection)_dbContext.Database.GetDbConnection();
var command = connection.CreateCommand();
command.CommandType = CommandType.StoredProcedure;
command.CommandText = strSQL;
foreach(var p in prms)
{
command.Parameters.Add("#" + p.Name, p.Value);
}
connection.Open();
var test = command.ExecuteNonQuery();
connection.Close();
Bus still no luck:
No mapping exists from object type Newtonsoft.Json.Linq.JValue to a known managed provider native type.
Is there any other way to execute stored procedure without mapping the entity?

You should be able to use normal SqlCommand and ExecuteReader method to get data from a stored procedure.
Quick sample.
This code executes a stored procedure called GetWidgets which expects 2 parameters, #name and #categoryId and returns a result set which has 2 columns, Id and Name. We are reading the value from the DataReader and creating an object of WidgetDto and appending to a list of WidgetDto.
Your WidgetDto is a simple POCO
public class WidgetDto
{
public int Id {set;get;}
public string Name {set;get;}
}
And the code to execute stored proc is
private List<WidgetDto> GetWidgets(d)
{
var catId= 1;
var name ="test"
//The above values are hard coded for demo. you may replace it
// with whatever your stored proc is expecting.
var list = new List<WidgetDto>();
const string sqlQry = "exec GetWidgets #name,#categoryId";
using (var db = new StudentsEntities())
{
using (var con = (SqlConnection) db.Database.Connection)
{
using (var cmd = new SqlCommand(sqlQry, con))
{
cmd.Parameters.AddWithValue("#name", name);
cmd.Parameters.AddWithValue("#categoryId", catId);
con.Open();
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var s = new GoodVm();
s.Id = reader.GetInt32(reader.GetOrdinal("Id"));
s.Name = reader.GetString(reader.GetOrdinal("Name"));
list.Add(s);
}
}
}
}
}
return list;
}
In this example, I am using db.DataBase.Connection (Available in ED 6.13 version) property of my DbContext to build the connection. You can build your connection from the legacy way also by using the connection string.

Related

How to build correct query notification?

could someone please help me, I'm trying to set up alerts with the total amount of records for some tables that I want. In this example, I'm just trying to return COUNT as a result of one of the tables to say how many records don't have schedules for the customer, however with all these exceptions
Creating a Query for Notification
,I couldn't think of a solution for my case.
SELECT COUNT(A.CODREF)QTDEAGENDSEMAGENDA FROM REGISTROS A INNER JOIN ATENDENTES U ON U.CODUSUARIO = A.CODUSUARIO WHERE A.CODUSUARIO = 11 AND A.STATUS IS NULL AND A.CODREF NOT IN ( SELECT CODREF FROM RETORNOS WHERE CODDIALOGO IS NULL AND AGEND_INTERNO IS NULL ) AND DATEDIFF(DAY, A.INICIO, GETDATE())> 11
All the queries I'm going to assemble will look like this in the example. I had thought of creating a view.
Calling my view:
SELECT QTDEAGENDSEMAGENDA FROM ALERTS
then the query would be simple and it would work, but I saw that it is also on the list not to be used.
This is my code and does not work with this query that I set up or with the View
public class NotificationHub : Hub
{
string qtdeAgendSemAgenda = string.Empty;
[HubMethodName("sendNotifications")]
public string SendNotifications()
{
using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
{
string query = #"SELECT COUNT(A.CODREF)QTDEAGENDSEMAGENDA FROM REGISTROS A INNER JOIN ATENDENTES U ON U.CODUSUARIO = A.CODUSUARIO WHERE A.CODUSUARIO = 11 AND A.STATUS IS NULL AND A.CODREF NOT IN ( SELECT CODREF FROM RETORNOS WHERE CODDIALOGO IS NULL AND AGEND_INTERNO IS NULL ) AND DATEDIFF(DAY, A.INICIO, GETDATE())> 11";
connection.Open();
using (SqlCommand command = new SqlCommand(query, connection))
{
command.Notification = null;
DataTable dt = new DataTable();
SqlDependency dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
if (connection.State == ConnectionState.Closed)
connection.Open();
var reader = command.ExecuteReader();
dt.Load(reader);
if (dt.Rows.Count > 0)
{
qtdeAgendSemAgenda = (dt.Rows[0]["QTDEAGENDSEMAGENDA"].ToString());
}
}
}
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();
return Tratar.String(context.Clients.All.RecieveNotification(qtdeAgendSemAgenda));
}

Create Data Dictionary to read column from DB

I am creating a WinForm Application that reads all the records from a certain column in a textfile. What I now need is a Data Dictionary that I can use to read records from the Database once the applications runs and prior to reading the TextFile. I need to read a specific column from the database and match it with the textfile. I am not sure how to go about creating a data dictionary. This is what I have so far.
This is to read the textfile, which is working fine.
using (StreamReader file = new StreamReader("C:\\Test1.txt"))
{
string nw = file.ReadLine();
textBox1.Text += nw + "\r\n";
while (!file.EndOfStream)
{
string text = file.ReadLine();
textBox1.Text += text + "\r\n";
string[] split_words = text.Split('|');
int dob = int.Parse(split_words[3]);
This is what I have so far to create the Data Dictionary.
public static Dictionary<int, string> dictionary = new Dictionary<int, string>();
You can use a SqlDataReader. Here is some code, you just need to modify it to suit your needs. I have added comments for you:
// declare the SqlDataReader, which is used in
// both the try block and the finally block
SqlDataReader rdr = null;
// Put your connection string here
SqlConnection conn = new SqlConnection(
"Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI");
// create a command object. Your query will go here
SqlCommand cmd = new SqlCommand(
"select * from Customers", conn);
try
{
// open the connection
conn.Open();
// 1. get an instance of the SqlDataReader
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
string id = (int)rdr["SomeColumn"];
string name = (string)rdr["SomeOtherColumn"];
dictionary.Add(id, name);
}
}
finally
{
// 3. close the reader
if (rdr != null)
{
rdr.Close();
}
// close the connection
if (conn != null)
{
conn.Close();
}
}

How to use SqlConnection InfoMessage

I have this method that calls a stored procedure. My problem is that it does not return a row, but it prints a message. I am trying to capture that print message into a variable. My problem is I have never ever used InfoMessage before and I checked it out online and for the life of me I can't seem to understand it. Can someone help me out or point me in the right direction?
Here is my code:
public List<showWhatClass> showWhatMethod(string deviceWhat, int tagWhat, Decimal latit, Decimal longit, int Process, string CallNext, int CallNextVar)
{
showWhatCell = new List<showWhatClass>();
try
{
using (connection = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand("iosShowWhat", connection))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("#DeviceId", deviceWhat);
command.Parameters.AddWithValue("#TagId", tagWhat);
command.Parameters.AddWithValue("#Latitude", latit);
command.Parameters.AddWithValue("#Longitude", longit);
command.Parameters.AddWithValue("#Process", Process);
command.Parameters.AddWithValue("#CallNext", CallNext);
command.Parameters.AddWithValue("#CallNextVar", CallNextVar);
connection.Open();
/*SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
showWhatClass item = new showWhatClass();
item.CallNext = reader.GetValue(0).ToString();
item.CallNextVar = (int)reader.GetValue(1);
showWhatCell.Add(item);
}*/
}
}
}
finally
{
connection.Close();
}
return showWhatCell;
}
I have tried the following:
connection.Open();
connection.InfoMessage += delegate(object sender, SqlInfoMessageEventArgs e)
{
showWhatClass item = new showWhatClass();
item.CallNext += "\n" + e.Message;
showWhatCell.Add(item);
};
returns nothing.
You can use an output parameter to get the message from stored procedure and use it in your code.
Add output parameter in stored procedure
#name varchar(20) output
And then set value of this parameter
set #name='Mairaj Ahmad Minhas'
Now in your code when you call stored procedure add another parameter like this
command.Parameters.Add("#name", SqlDbType.VarChar, 20);
command.Parameters["#name"].Direction = ParameterDirection.Output;
And after you have called the stored procedure do this to get value from this parameter.
string name = command.Parameters["#name"].Value.ToString();

ASP.NET select * from table and save them in variable

I'am new in asp.net. I want to select values from database table.
If it was PHP I would do it like following code.
$query = mysql_query(" SELECT * FROM Table WHERE id = ".$d." ");
while($row = mysql_fetch_array($query))
{
$firstname = $row['firstname'];
$lastname = $row['lastname'];
}
How would I do if it was in asp.net if I use SqlConnection ...and SqlCommand or maybe if there is some beter Connections.... Thank you in advance guys....
//Create a command, using a parameter
var command = new SqlCommand("select firstname, lastname from table where id=#id");
command.Parameters.AddWithValue("id", id);
DataTable dt = new DataTable();
//use a using statement to ensure the connection gets disposed properly
using(var connection = new SqlConnection("connectionstring"))
{
command.Connection = connection;
connection.Open();
//execute the command and load the results in a data table
dt.Load(command.ExecuteReader());
}
//loop through the results of the data table
foreach(var row in dt.Rows)
{
var firstname = row.Field<string>("firstname");
var lastname = row.Field<string>("lastname");
//do something with firstname and lastname
}
This isn't a direct translation since I'm storing the values in a DataTable, but that is usually better than leaving the data connection open.

Nested Queries In ASP.Net Without Async

I have the following code and basically I want it go step by step using the If statements. When I run this however I get this asp error: "This command requires an asynchronous connection. Set "Asynchronous Processing=true" in the connection string."
On this bit of code:
"addToTable.BeginExecuteReader();"
However I do not want it to by async I want it to run the subsequent queries only if the previous conditions are met.
Full code is below:
string dataset="";
if (System.Web.HttpContext.Current.Session["user"] != null)
{
if (name != null && carId != null)
{
using (SqlConnection con = new SqlConnection(st))
{
string getCar = "SELECT * FROM [Car] WHERE CarId = #carId";
SqlCommand cmd = new SqlCommand(getCarData, con);
cmd.Parameters.AddWithValue("#carId", carId);
using (cmd)
{
con.Open();
SqlDataReader data = cmd.ExecuteReader();
if (data.HasRows)
{
while (data.Read())
{
if (data["available"].ToString() == "0")
{
data.Close();
SqlCommand getParts = new SqlCommand("SELECT * FROM [CarCustomer] WHERE UserId = #UserId AND car=#carId", con);
getParts.Parameters.AddWithValue("#userId", System.Web.HttpContext.Current.Session["userId"]);
getParts.Parameters.AddWithValue("#carId", carId);
SqlDataReader grabRows = getParts.ExecuteReader();
if (grabRows.HasRows)
{
grabRows.Close();
SqlCommand updateTable = new SqlCommand("UPDATE [Table1] SET salesAmount=5 WHERE UserId=1", con);
updateTable.BeginExecuteReader();
}
else
{
grabRows.Close();
SqlCommand addToTable = new SqlCommand("INSERT INTO [Table1] (salesAmount) Values("1")", con);
addToTable.BeginExecuteReader();
}
dataset="good"
}
}
}
}
}
}
}
return dataset;
Instead of BeginExecuteReader command use SqlCommand.ExecuteNonQuery , because ExecuteNonQuery is used to perform query like insert,update and delete where as for Gettting data Read method is used.
one more thing BeginExecuteReadermethod is used to perfrom asncy read operation so if you dont want that than just use ExecuteReadermethod to get data.
Read SqlCommand.ExecuteNonQuery -
You can use the ExecuteNonQuery to perform catalog operations (for example, querying the structure of a database or creating database objects such as tables), or to change the data in a database without using a DataSet by executing UPDATE, INSERT, or DELETE statements.

Resources