How to use stored procedure on MVC 5 with DbContext? - stored-procedures

In SQL 2008 Query I just execute and it returns 1 if successful. Now how do I do this in MVC 5 EF dbcontext?
usp_CreateNewAccount usernamehere, passwordhere, emailhere
I created my Controller item using the Entity Framework, and edit the controller Create method.
db.Users.Add(user);
db.Users.SqlQuery("usp_CreateNewAccount fsdfsdf, sdfsdfsd, dasda");
db.SaveChanges();
it gives no result. I can't create user. Any possible solution?

Suppose you have stored procedure usp_CreateNewAccount:
CREATE PROCEDURE usp_CreateNewAccount
#usernamehere NVARCHAR(...),
#passwordhere NVARCHAR(...),
#emailhere NVARCHAR(...)
AS
BEGIN
-- insert query here
END
Then you can use DbContext.Database.SqlQuery with parameters like this one:
using (var db = new DataContext()) // DataContext is your DBContext name
{
var userName = new SqlParameter()
{
ParameterName = "usernamehere",
DbType = DbType.String,
Value = "fsdfsdf"
};
var password = new SqlParameter()
{
ParameterName = "passwordhere",
DbType = DbType.String,
Value = "sdfsdfsd"
};
var email = new SqlParameter()
{
ParameterName = "emailhere",
DbType = DbType.String,
Value = "dasda"
};
// suppose "User" table exists with "db.Users" as DbSet<User> collection
db.Database.SqlQuery<User>("EXEC usp_CreateNewAccount {0}, {1}, {2}", new Object[] { userName, password, email });
}
There's no reason to use db.Users.Add and db.SaveChanges method here since insert and save operation already handled by stored procedure query.

Related

Linq query returns sql and not data from database

I'm not sure what the problem is but I cant seem to get my program to display the correct information. The requirements for my application are to take a pdf and populate the form fields with information from a database. The problem is that it does not return the information from the database and instead returns the sql generated from entity framework.
(text) SELECT
[Extent1].[Applicant_ID] AS [Applicant_ID]
FROM [dbo].[W4] AS [Extent1]
This is what is displayed in the pdf textbox.
This is my query
public class Query
{
ApplicatoinContext context = new ApplicatoinContext();
public List<W4> GetId()
{
return (from p in context.w4
select new W4 { Applicant_ID = p.Applicant_ID }).ToList();
}
}
My controller
public class ApplicationController : Controller
{
// GET: Application
public ActionResult Index()
{
string template = #"c:\users\carisch\documents\visual studio 2013\Projects\Idea\Idea\fw4.pdf";
string newFile = #"c:\users\carisch\documents\visual studio 2013\Projects\Idea\Idea\Newfw4.pdf";
PdfReader reader = new PdfReader(template);
PdfStamper stamper = new PdfStamper(reader, new FileStream(newFile, FileMode.Create));
AcroFields fields = stamper.AcroFields;
Query num = new Query();
var query = num.GetId();
fields.SetField("f1_15_0_", query.ToString());
stamper.FormFlattening = false;
stamper.Close();
return File(#"c:\users\carisch\documents\visual studio 2013\Projects\Idea\Idea\Newfw4.pdf", "application/pdf");
}
}
I'm pretty new to programming so any help would be greatly appreciated.

How to insert a list of objects using stored proc in ado.net

Let's say I have this method
public static void LockPerformanceToDB(List<performance> listOfPerformances)
{
//Do I need just to wrap this call with a loop? ...
using(var con = new OpenConnection)
{
//I call the LockPerformanceToDB SPROC here ...
}
}
I also have this procedure in the database:
CREATE PROCEDURE LockPerformancesToDB
#UserId INT,
#Comments VARCHAR(50),
#TimeStamp DATETIME
AS
BEGIN
INSERT INTO Performance
(UserId, Comments, [TimeStamp])
VALUES
(#UserId, #Comments, #TimeStamp)
END
This sproc handles one insertion at time. As it's obvious that the list has several of the same performance objects. Is looping through each object of the list the solution?
I'd like to know whether there is a different solution besides looping and calling the sproc as many times as there are objects in the lisOfPerformances?
Thanks for helping
Why not use Table-Valued Parameters to pass multiple rows to the stored procedure.
Table-valued parameters are declared by using user-defined table types. You can use table-valued parameters to send multiple rows of data to a Transact-SQL statement or a routine, such as a stored procedure or function, without creating a temporary table or many parameters.
Create the type
Create Type TVP_LockPerformancesToDB As Table(
UserId int, Comments varchar(50), [TimeStamp] datetime)
Create the stored procedure as
CREATE PROCEDURE LockPerformancesToDB2
#CommentInfo TVP_LockPerformancesToDB READONLY
AS
BEGIN
INSERT INTO Performance
(UserId, Comments, [TimeStamp])
SELECT UserId, Comments, [TimeStamp]
FROM #CommentInfo
END
Then in your code
class Performance
{
public int UserId { get; set; }
public string Comments { get; set; }
public DateTime TimeStamp { get; set; }
}
List<Performance> listOfPerformances = new List<Performance>() {
new Performance{ UserId=1, Comments="First", TimeStamp=DateTime.Now},
new Performance{ UserId=2, Comments="Second", TimeStamp=DateTime.Now},
new Performance{ UserId=3, Comments="Third", TimeStamp=DateTime.Now}
};
SqlCommand cmd = new SqlCommand();
var dt = new DataTable();
dt.Columns.Add("UserId", typeof(Int32));
dt.Columns.Add("Comments", typeof(string));
dt.Columns.Add("TimeStamp", typeof(DateTime));
for (int i = 0; i < listOfPerformances.Count; i++)
{
dt.Rows.Add(listOfPerformances[i].UserId, listOfPerformances[i].Comments, listOfPerformances[i].TimeStamp);
}
cmd.Connection = conn;
cmd.CommandText = "LockPerformancesToDB2";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("CommentInfo", SqlDbType.Structured));
cmd.Parameters["CommentInfo"].Value = dt;
cmd.ExecuteNonQuery();

how to retrieve values from Session object in mvc3?

I have mvc 3 application in which in session object I'm taking all values that is needed to me as parameter to execute stored procedure.
If the userAction is update then execute stored procedure.
public ActionResult Index(string userAction)
{
if(Session["Mappings"] != null)
ViewData["Message"] = "Mapping web grid";
if (Session["PricingSecurities"] == null)
Session["PricingSecurities"] = objRepository.GetPricingSecurityID();
if (Session["Cusips"] == null)
Session["Cusips"] = objRepository.GetCUSIP();
SecurityMappingModel objModel = null;
mappings = (List<SecurityMappingModel>)Session["Mappings"];
objModel = new SecurityMappingModel();
if (userAction == "Update" )
{
//please tell me how can i take values from Session[Mappings] and pass it to stored procedure?
//i'm trying this code
//foreach (var item in Session)
//{objModel.Cusips = (List<SelectListItem>)Session["Mappings"];
//I did function import here (import my sp in model)using EF name
//ExecuteMappingsp.
//dbContext.ExecuteMappingsp(need to pass parameter);
//} //i know wrong code but how to fix this??
// PLEASE HELP ME TO RETRIEVE SESSION VALUES
return RedirectToAction("Index");
}
objModel.PricingSecirities = (List<SelectListItem>)Session["PricingSecurities"];
objModel.Cusips = (List<SelectListItem>)Session["Cusips"];
ViewBag.Mappings = mappings;
return View(objModel);
}
How can I take values from Session[Mappings] and pass it to stored procedure?
Description
Entity Framework Code First does not support stored procedure calls at the moment. The only way to do this, at the moment, is to use the SqlCommand. (System.Data.SqlClient namespace)
Sample
// ....
if (userAction == "Update")
{
// Create SqlCommand with your stored procedure name and sql connectionstring
SqlCommand cmd = new SqlCommand("dbo.StoredProcedureName", new SqlConnection("ConnectionString"));
// set the command type to StoredProcedure
cmd.CommandType = System.Data.CommandType.StoredProcedure;
// Add Parameters
cmd.Parameters.Add("#ParameterName", Session[Mappings]);
// execute the stored procedure
cmd.ExecuteNonQuery();
return RedirectToAction("Index");
}
More Information
MSDN - Using Stored Procedures with a Command
Update
I can't know your Model and if it is code first, database first or shema first because you don't provide that information. But maybe this helps
foreach (var item in (List<SelectListItem>)Session["Mappings"])
{
dbContext.ExecuteMappingsp(PassInTheParametersYouNeedFromYourItem)
}

MVC Entity Framework - Inserting Data - A dependent property in a ReferentialConstraint is mapped to a store-generated column

I need help with trying to insert a record using MVC and Entity Framework. I have a dynamically created form which can contain many questions. When Editing, I want to delete the existing answers (which it does successfully) and insert new answers.
I am getting the following error:
Cannot insert explicit value for identity column in table 'tblModeratorReportAnswers' when IDENTITY_INSERT is set to OFF.
If I add the following line in my DbContext class
modelBuilder.Entity<QuestionAnswer>().Property(p => p.AnswerID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); I get this error:
A dependent property in a ReferentialConstraint is mapped to a store-generated column. Column: 'AnswerID'.
Here's my code that is doing the update
//
// POST: /Home/Edit/1
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(FormCollection formCollection, int moderatorReportId)
{
ModeratorReport reportToEdit = repository.GetModeratorReportById(moderatorReportId);
List<QuestionAnswer> originalReportAnswers = repository.GetAllModeratorReportAnswers(moderatorReportId).ToList();
foreach (QuestionAnswer answer in originalReportAnswers) {
repository.DeleteAnswer(answer);
}
repository.Save();
int sectionID;
int questionID;
foreach (string key in formCollection.AllKeys)
{
var value = formCollection[key.ToString()];
Match m = Regex.Match(key, "section(\\d+)_question(\\d+)");
if (m.Success) {
QuestionAnswer newAnswer = new QuestionAnswer();
sectionID = Convert.ToInt16(m.Groups[1].Value.ToString());
questionID = Convert.ToInt16(m.Groups[2].Value.ToString());
newAnswer.ModeratorReportID = moderatorReportId;
newAnswer.QuestionID = questionID;
newAnswer.Answer = value;
repository.AddAnswer(newAnswer);
}
}
repository.Save();
reportToEdit.Status = "SUBJECTOFFICER SAVED";
AuditItem auditItem = new AuditItem();
auditItem.ModeratorReportID = moderatorReportId;
auditItem.Status = "SUBJECTOFFICER SAVED";
auditItem.AuditDate = DateTime.Now;
auditItem.Description = "The Moderator report ID: " + moderatorReportId + " was saved.";
auditItem.UserID = User.Identity.Name;
db.Audit.Add(auditItem);
repository.Save();
return RedirectToAction("Details", new { id = moderatorReportId });
}
...and in my repository
//
// Persistance
public void Save()
{
db.SaveChanges();
}
public void AddAnswer(QuestionAnswer answer)
{
db.Answers.Add(answer);
Save();
}
public void DeleteAnswer(QuestionAnswer answer)
{
db.Answers.Attach(answer);
db.Answers.Remove(answer);
}
I have also checked all my Primary Keys, Foreign Keys and they are all ok. The Primary Keys are all set to 'Is Identity'.
I've been trying to sort this problem out all day. I have no idea what to do to resolve it. If anyone can give my any advice, it'd be much appreciated.
Maybe it's my inexperience with ASP.NET MVC and Entity Framework, but I have now resolved this issue by changing the logic of that I update the report.
Instead of deleting the answers and reinserting them. I now retrieve the answers and change Answer property to be the new answer. Then just use db.SaveChanges().
//
// POST: /Home/Edit/1
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(FormCollection formCollection, int moderatorReportId)
{
ModeratorReport reportToEdit = repository.GetModeratorReportById(moderatorReportId);
List<QuestionAnswer> originalReportAnswers = repository.GetAllModeratorReportAnswers(moderatorReportId).ToList();
int sectionID;
int questionID;
foreach (string key in formCollection.AllKeys)
{
var value = formCollection[key.ToString()];
Match m = Regex.Match(key, "section(\\d+)_question(\\d+)");
if (m.Success) {
QuestionAnswer newAnswer = new QuestionAnswer();
sectionID = Convert.ToInt16(m.Groups[1].Value.ToString());
questionID = Convert.ToInt16(m.Groups[2].Value.ToString());
foreach(QuestionAnswer answerToEdit in originalReportAnswers) {
if (answerToEdit.QuestionID == questionID)
{
answerToEdit.Answer = value;
}
}
}
}
repository.Save();
reportToEdit.Status = "SAVED";
AuditItem auditItem = new AuditItem();
auditItem.ModeratorReportID = moderatorReportId;
auditItem.Status = "SAVED";
auditItem.AuditDate = DateTime.Now;
auditItem.Description = "The Moderator report ID was saved.";
auditItem.UserID = User.Identity.Name;
db.Audit.Add(auditItem);
repository.Save();
return RedirectToAction("Details", new { id = moderatorReportId });
}
Cannot insert explicit value for identity column in table
'tblModeratorReportAnswers' when IDENTITY_INSERT is set to OFF.
This error says that you are explicitly inserting value into autogenerated column (identity column).
A dependent property in a ReferentialConstraint is mapped to a
store-generated column. Column: 'AnswerID'.
This error says that there is some incorrectly configured relation where autogenerated AnswerID is considered as FK - that is not supported. Identity and Computed properties must not be FKs.

Asp.Net MVC 3 - Linq To Entities - PK with Null doesn't get inserted into the db (don't want null :))

I'm using the latest Asp.Net MVC version.
For some reason, when my POST (Action Create) in my controller gets hit.
I can't seem to be able to add it to the entityset.
What i have is,
1) My EntityModel (*.edmx file)
2) Controller which references the entity:
private db.DataContainer _db = new db.DataContainer();
3) My method (i'm using Guid as pk):
[HttpPost]
public ActionResult Create(Client client)
{
try
{
client.Id = Guid.NewGuid();
/* method 2
Client cl = new Client();
cl.Id = Guid.NewGuid();
cl.email = client.email;
cl.Adres = client.Adres;
cl.companyName = client.companyName;
cl.fax = client.fax;
cl.phone = client.phone;
*/
// client.Id = Guid.NewGuid();
_db.ClientSet.AddObject(client);
_db.SaveChanges();
return RedirectToAction("Index");
}
catch (Exception ex)
{
var ex_message = ex.Message;
var ex_data = ex.Data;
var ex_ix = ex.InnerException;
return View();
}
}
4) Following is my InnerException:
[System.Data.SqlClient.SqlException] = {"Cannot insert the value NULL into column 'Id', table 'lst.dbo.ClientSet'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated."}
Both doesn't seem to work :(
GUIDs are not supported as primary keys in the Entity Framework. You will need to modify your save method to generate a new GUID for your added objects http://msdn.microsoft.com/en-us/library/dd283139.aspx
It seems that changing my "saveCommand" has given my a temporarily solution:
I chaned:
_db.SaveChanges()
To
_db.SaveChanges(System.Data.Objects.SaveOptions.None);

Resources