I have one Stored Procedure with different actions in it. For Eg - Insert, select, update all are in one stored procedure and I execute it using a if else condition.
BEGIN
if(#type = 'add')
INSERT INTO [dbo].[napme]
([firstname]
,[lastname]
,[Address]
,[City])
VALUES
(#firstname,#lastname,#Address,#City)
if(#type = 'select')
select * from napme
END
Now can I use that procedure in MVC using Entity Framework. If so how?
Once such method is mapping the parameters but I am unable to map #type
Can anyone suggest any easy way
You can try like this
var courseList = ctx.Database.SqlQuery<YourEntityName>("exec ProcName #Param1", Param1).ToList<YourEntityName>();
If you plan on using Code-First EntityFramework then you can map Insert, Update and Delete operations to stored procedures if you wish.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder
.Entity<YourEntityClass>()
.MapToStoredProcedures();
}
With a SP example like so:
CREATE PROCEDURE [dbo].[YourEntityClass_Insert]
#param1 nvarchar(max),
#param2 nvarchar(max)
AS
BEGIN
INSERT INTO [dbo].[YourEntityClass] ([col1], [col2])
VALUES (#param1, #param2)
Look here for more information.
If you plan on executing a SP for other reasons (non CRUD) then you will have to execute a SP as per bharats answer.
Related
I have installed EF Core 5 Power Tools to Add a DB with stored procedure to an ASP.NET Core project. the models are successfully generated by Power Tools and the tables work fine; but when i try to retrieve a result set out of a stored procedure and store it to a ViewBag to display on the View, the value stored at Viewbag is weird and has nothing to do with a result set.
Here is the stored procedure code at db, which is pretty simple, just to test Power Tools:
CREATE PROCEDURE retTable (#P INT)
AS
BEGIN
SELECT * FROM STU WHERE ID=#P;
END;
Controller:
public IActionResult Index()
{
schoolContext s = new schoolContext();
schoolContextProcedures sp = new schoolContextProcedures(s);
var t = sp.retTableAsync(20); // The built is perfectly done, but the value store instead of result set is weird
ViewBag.test = t;
return View();
}
and just added a #View.Bag to the view to make sure it's displayed, Though the app's built is done successfully without any error, This is what's displayed at the View instead of ViewBag value:
System.Runtime.CompilerServices.AsyncTaskMethodBuilder1+AsyncStateMachineBox1[System.Collections.Generic.List`1[WebApplication2.Models.DB.retTableResult],WebApplication2.Models.DB.schoolContextProcedures+d__3]
Tried to convert the result set to a list or something else but it's not working :|
Anyone know how to fix it?
The value stored in it is not "weird", its a Task.
Since your method is async, you should await for the result of the returned task, not the "return" itself, as this is only a reference to the task that is executed asynchronusly.
As martin smith mentions, just:
var t = await sp.retTableAsync(20);
Otherwise you are adding a task as the viewbag property, instead of the task result once completed
I have requirement like to call the stored procedures to get the data, here i will get the stored procedure name through post data.
I tried using GString but no use, Can any one help me to solve this issue.
Thanks in advance.
This is a weird one, but possible. Grails/GORM doesn't provide a way to execute stored procedures. It's just not part of ORM functionality. And neither does Hibernate. But, Hibernate does provide access to a JDBC connection. So you can get a connection from Hibernate, then create a Groovy Sql instance with the connection, and finally execute your stored procedure. Here's an example:
import groovy.sql.Sql
SomeDomainClass.withNewSession { session ->
session.doWork { java.sql.Connection connection ->
def sql = new Sql(connection)
sql.call("YOUR STORED PROCEDURE SQL HERE")
}
}
It works like this:
Using any of your domain classes, call withSession(Closure) to get a Hibernate session.
With the session, call doWork(Work) to get access to the session's JDBC connection. Now, doWork(Work) expects an implementation of org.hibernate.jdbc.Work. But, if I recall correctly, Groovy can take a closure with the same parameters and coerce it to implement the interface.
Using the connection, create an instance of Sql. You could skip this and query with Java, but Groovy's Sql class is so nice.
Use one of the available Sql.call() methods to execute your stored procedure.
In postgress SQL, it is posible to call stored procedure. The catch is returning a data table so that you can map it to a model. This is as shown bellow.
create function activate(confirmationcode text)
returns TABLE(resultid integer, resultmessage character varying)
language plpgsql
as $$
BEGIN
....
END
This can be invoked as follows in GORM db connections
type FuncResult struct {
Resultid int
Resultmessage string
}
...
fResult := FuncResult{}
err := s.db.Raw("SELECT * from activate(?)", token).Scan(&fResult).Error
I am using ORM Lite's .SqlList method to call a stored procedure and map the results to my custom object. When I am using only one parameter, and calling the stored procedure as follow it works fine:
var results = conn.SqlList<CustomObject>("EXEC MyStoredProcedure #paramOne"), new { paramOne = "someParam" });
When I want to call a stored procedure with more than one parameter and I call it as shown bellow I get an error stating that "The given key was not present in the dictionary.".
var results = conn.SqlList<CustomObject>("EXEC MyStoredProcedure #paramOne, #paramTwo"), new { paramOne = "someParam", paramTwo = "someOtherParam" });
I had a look at the sql stored procedure test page on the ORM Lite Github repo but it does not show how to call stored procedures with more that one param.
Thanks.
EDIT:
I should add that the second parameter on the sql side is a custom table type, and I am sending in a DataTable type in C#.
I am using ASP.NET MVC 3 and EF 4.x
I have a procedure that returns a result set but the columns are not fixed (it may return 25 columns or may be 40 or 50).
How can I call this stored procedure from Entity Framework?
When I use function import it asks for an Entity. But I cannot select it as none of the columns is fixed.
Entity Framework is not the right tool for this. It is good at statically defined data structures, not at dynamic ones.
There are better tools for this. I would recommend Dapper, created by Marc Gravell. It's easy as pie. Just get the NuGet package and type something like
using Dapper;
using (var cnn = new SqlConnection(myConnectionString))
{
cnn.Open();
var p = new DynamicParameters();
p.Add("#params", "Id=21");
var results = cnn.Query(sql:"GetMyData",
param: p,
commandType: CommandType.StoredProcedure);
foreach(IDictionary<string, object> result in results)
{
// Do something here.
}
}
Query is a Dapper extension method, result is a DapperRow, which is a private class that implements IDictionary<string, object>, so you can just access your data as a dictionary per record.
Aside from being easy to use, it's lightning fast too.
Does BLT support Oracle stored procedures? I've tried numerous methods, described below to get it to work but no luck. The stored procedure updates a table with several values. This is the stored procedure, a small test procedure.
DROP PROCEDURE BETA_AUTO_UPDATE;
/
CREATE OR REPLACE PROCEDURE BETA_AUTO_UPDATE
(
AutoId IN NUMBER,
Rule IN NVARCHAR2,
Nam IN NVARCHAR2,
Loc IN NVARCHAR2
)
IS
BEGIN
UPDATE Beta_Auto
SET RuleGuid = Rule,
Name = Nam,
Location = Loc
WHERE Id=AutoId;
EXCEPTION
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20001, 'ERROR OCCURED DURING UPDATE');
END BETA_AUTO_UPDATE;
/
Tried the following
DbManager.AddDataProvider(new OdpDataProvider());
DbManager OracleDb = new DbManager("BetaOracleDBConn");
Beta_Auto Betar = new Beta_Auto();
Betar.ID = 1;
Betar.Name = "Jim";
Betar.RuleGuid = "jlDKDKDKDKDKDKp";
Betar.Location = "LocDLDLDLDLDtor";
OracleDb.SetSpCommand("Beta_Auto_UPDATE",
OracleDb.CreateParameters(Betar)).ExecuteNonQuery();
That didn't work.
Tried this
[ActionName("UPDATE")]
public abstract void Update(Beta_Auto Auto);
That didn't work.
Tried this:
[SprocName("Beta_Auto_Update")]
public abstract void UpdateByParam(
[Direction.InputOutput("ID", "RuleGuid", "Name", "Location")] Beta_Auto Auto);
That didn't work.
[SprocName("Beta_Auto_Update")]
public abstract void UpdateByParam(int Id, string RuleGuid, string Name, string Location);
Also tried this:
[ActionName("Update")]
public abstract void UpdateByParam(int Id, string RuleGuid, string Name, string Location);
That didn't work.
Set the trace level on odp.net to 7. Saw that the call was being made, but couldn't see any parameters. Swapped out XE (thought it might have been a licensing problem as db was bigger that 5GB) for enterprise Oracle. Didn't work.
Create a new user, datafile, tablespace, and assigned all roles and privs, including Execute Any Procedure to the user. Didn't work.
I ran a standard ado.net (very long winded) to call the stored procedure via OracleCommand and it called perfectly and did the update.
I am stumped. All of the above work for SQL Server.
Thanks.
scope_creep
I'm doing it like
var parameters = OracleDb.GetSpParameters("BETA_AUTO_UPDATE", true, true);
parameters.SetParamValue("pParam1", param1);
parameters.SetParamValue("pParam2", param2);
...
OracleDb.SetSpCommand("BETA_AUTO_UPDATE", parameters).ExecuteNonQuery();
It's an extra round-trip, but since I'm only using stored procedures for a couple of big batch updates it doesn't really matter, (normal/simple updates are done with Linq DML operations)