How to call Stored Procedures with EntityFramework?
Solution 1
One way is to use the Database property off the DbContext:
SqlParameter param1 = new SqlParameter("@firstName", "Frank");
SqlParameter param2 = new SqlParameter("@lastName", "Borland");
context.Database.ExecuteSqlCommand("sp_MyStoredProc @firstName, @lastName",
param1, param2);
EF5 definitely supports that.
Solution 2
You have use the SqlQuery function and indicate the entity to mapping the result.
I send an example as to perform this:
var oficio= new SqlParameter
{
ParameterName = "pOficio",
Value = "0001"
};
using (var dc = new PCMContext())
{
return dc.Database
.SqlQuery<ProyectoReporte>("exec SP_GET_REPORTE @pOficio",
oficio)
.ToList();
}
Solution 3
Once your stored procedure is imported in your model, you can right click in it (from the model browser, in the Context.Store
/Stored Procedures
section), and click Add Function Import
. If you need a complex type as a result, you can create it right there.
Solution 4
Based up the OP's original request to be able to called a stored proc like this...
using (Entities context = new Entities())
{
context.MyStoreadProcedure(Parameters);
}
Mindless passenger has a project that allows you to call a stored proc from entity frame work like this....
using (testentities te = new testentities())
{
//-------------------------------------------------------------
// Simple stored proc
//-------------------------------------------------------------
var parms1 = new testone() { inparm = "abcd" };
var results1 = te.CallStoredProc<testone>(te.testoneproc, parms1);
var r1 = results1.ToList<TestOneResultSet>();
}
... and I am working on a stored procedure framework (here) which you can call like in one of my test methods shown below...
[TestClass]
public class TenantDataBasedTests : BaseIntegrationTest
{
[TestMethod]
public void GetTenantForName_ReturnsOneRecord()
{
// ARRANGE
const int expectedCount = 1;
const string expectedName = "Me";
// Build the paraemeters object
var parameters = new GetTenantForTenantNameParameters
{
TenantName = expectedName
};
// get an instance of the stored procedure passing the parameters
var procedure = new GetTenantForTenantNameProcedure(parameters);
// Initialise the procedure name and schema from procedure attributes
procedure.InitializeFromAttributes();
// Add some tenants to context so we have something for the procedure to return!
AddTenentsToContext(Context);
// ACT
// Get the results by calling the stored procedure from the context extention method
var results = Context.ExecuteStoredProcedure(procedure);
// ASSERT
Assert.AreEqual(expectedCount, results.Count);
}
}
internal class GetTenantForTenantNameParameters
{
[Name("TenantName")]
[Size(100)]
[ParameterDbType(SqlDbType.VarChar)]
public string TenantName { get; set; }
}
[Schema("app")]
[Name("Tenant_GetForTenantName")]
internal class GetTenantForTenantNameProcedure
: StoredProcedureBase<TenantResultRow, GetTenantForTenantNameParameters>
{
public GetTenantForTenantNameProcedure(
GetTenantForTenantNameParameters parameters)
: base(parameters)
{
}
}
If either of those two approaches are any good?
Solution 5
Basically you just have to map the procedure to the entity using Stored Procedure Mapping.
Once mapped, you use the regular method for adding an item in EF, and it will use your stored procedure instead.
Please see: This Link for a walkthrough. The result will be adding an entity like so (which will actually use your stored procedure)
using (var ctx = new SchoolDBEntities())
{
Student stud = new Student();
stud.StudentName = "New sp student";
stud.StandardId = 262;
ctx.Students.Add(stud);
ctx.SaveChanges();
}
Ivy
Updated on May 12, 2020Comments
-
Ivy almost 4 years
I have generated an EF4 Model from a MySQL database and I have included both StoredProcedures and Tables.
I know how to make regular instert/update/fetch/delete operations against the EF but I can't find my StoredProcedures.
This was what I was hoping for:
using (Entities context = new Entities()) { context.MyStoreadProcedure(Parameters); }
Edit 1:
This is how it looked without EF:
sqlStr = "CALL updateGame(?,?,?,?,?,?,?)"; commandObj = new OdbcCommand(sqlStr, mainConnection); commandObj.Parameters.Add("@id,", OdbcType.Int).Value = inGame.id; commandObj.Parameters.Add("@name", OdbcType.VarChar, 255).Value = inGame.name; commandObj.Parameters.Add("@description", OdbcType.Text).Value = ""; //inGame.description; commandObj.Parameters.Add("@yearPublished", OdbcType.DateTime).Value = inGame.yearPublished; commandObj.Parameters.Add("@minPlayers", OdbcType.Int).Value = inGame.minPlayers; commandObj.Parameters.Add("@maxPlayers", OdbcType.Int).Value = inGame.maxPlayers; commandObj.Parameters.Add("@playingTime", OdbcType.VarChar, 127).Value = inGame.playingTime; return Convert.ToInt32(executeScaler(commandObj));
PS. I can change EF version if needed
Edit 1:
CREATE DEFINER=`106228`@`%` PROCEDURE `updateGame`( inId INT, inName VARCHAR(255), inDescription TEXT, inYearPublished DATETIME, inMinPlayers INT, inMaxPlayers INT, inPlayingTime VARCHAR(127) )
-
Ivy over 11 yearsI dont get it, why should i hardcode the SP name? I have added them when generating the Model? Should thay not just be somewhere on the Context object as methods?
-
Ivy over 11 yearsI dont get it, why should i hardcode the SP name? I have added them when generating the Model? Should thay not just be somewhere on the Context object as methods?
-
Quinton Bernhardt over 11 yearsYeah, this is the way to do it if you haven't linked it to your model and you want raw access ;)
-
Ivy over 11 yearsTried this but it does not generate a method with parameters? Not sure how to putt in the parameters?
-
user1908061 over 11 yearsWhen the procedure has parameters, then they will be added.
-
ESG over 11 yearsIt does for me, using framework 4. Can you show the create statement of the procedure? (Only with the parameters)
-
ESG over 11 yearsSo, you don't have anything strange in there. It really should support parameters, I'm not sure why it's not. Can you try it with a procedure with only a few parameters, like 3 ints, see what it does?
-
Ivy over 11 yearsI tried to add one with only one parameter and its not working
-
Ivy over 11 yearsThanks! Yes probalby, I will have to do this manually becouse I can´t update the MySQL server.
-
ESG over 11 yearsYou might be able to fix it by using a different version of your driver.
-
Admin over 7 yearsThis just executes the stored proc as non-query. It cannot read any returned tables
-
Admin over 7 yearsYou have to declare your
ProyectoReporte
class that represents the result table returned by query -
Gert Arnold almost 6 yearsDespite all the answers this is the only answer OP was looking for.