Stored Procedure is not called when send request along with parameters - c#

I have an ASP.NET MVC application in C# where I am calling a stored procedure CreateFunctionNavigation. I am having issue calling that stored procedure along with parameters. I have model class as;
Model class
public class CreateFunctionNavigation_SP_Map
{
public CreateFunctionNavigation_SP_Map()
{
}
[StringLength(250)]
[Required(ErrorMessage = "Required Function Title")]
[Display(Name = "Function Title")]
public string FunctionName { get; set; }
[Required(ErrorMessage = "Required Function Hierarchy; i.e Where Function Exists In Hierarchy Tree \n Top-Level Start From 1 ")]
[Display(Name = "Function Hierarchy Level")]
public int FunctionHierarchy_Level { get; set; }
[StringLength(250)]
[Required(ErrorMessage = "Required Controller Title")]
[Display(Name = "Controller Title")]
public string ControllerName { get; set; }
[StringLength(250)]
[Required(ErrorMessage = "Required Action Title")]
[Display(Name = "Action Title")]
public string ActionName { get; set; }
[Required(ErrorMessage = "Required Function Parent - Child Relation ID \n Put 0 In Case Given Function doesn't Have Any Parent Function ")]
[Display(Name = "Function Parent's FunctionID")]
public int Function_ParentsFunctionID { get; set; }
}
Stored procedure:
ALTER PROCEDURE [dbo].[CreateFunctionNavigation]
#FunctionName nvarchar(250),
#Hierarchy_Level INT,
#Function_identity INT OUTPUT,
#ControllerName nvarchar(250),
#Controller_identity INT OUTPUT,
#ControllerInFunction_identity INT OUTPUT,
#ActionName nvarchar(250),
#Action_identity INT OUTPUT,
#ActionInFunction_identity INT OUTPUT,
#Function_ParentsFunctionID INT,
#Function_ParentsFunction_identity INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [dbo].[Navigation_Functions] ([FunctionName],[Hierarchy_Level])
VALUES(#FunctionName, #Hierarchy_Level)
SET #Function_identity = SCOPE_IDENTITY()
INSERT INTO [dbo].[Navigation_FunctionController] ([ControllerName])
VALUES(#ControllerName)
SET #Controller_identity = SCOPE_IDENTITY()
INSERT INTO [dbo].[Navigation_FunctionInController] ([Function_ID], [ControllerID])
VALUES (#Function_identity, #Controller_identity)
SET #ControllerInFunction_identity = SCOPE_IDENTITY()
INSERT INTO [dbo].[Navigation_FunctionAction] ([ActionName], [ControllerID])
VALUES (#ActionName, #Controller_identity)
SET #Action_identity = SCOPE_IDENTITY()
INSERT INTO [dbo].[Navigation_FunctionInAction] ([ActionID], [Function_ID])
VALUES (#Action_identity, #Function_identity)
SET #ActionInFunction_identity = SCOPE_IDENTITY()
INSERT INTO [dbo].[Navigation_FunctionHierarchy] ([Function_IDs], [Parent_Function_ID])
VALUES (#Function_identity, #Function_ParentsFunctionID)
SET #Function_ParentsFunction_identity = SCOPE_IDENTITY()
RETURN
END
now in C# class I am trying to run this stored procedure with passing parameters but in SQL Server Profiler I cannot see if this stored procedure is not called.
C# Code to run stored procedure
var _result = dbContext.Database.SqlQuery<CreateFunctionNavigation_SP_Map>("exec CreateFunctionNavigation #FunctionName #FunctionHierarchy_Level #ControllerName #ActionName #Function_ParentsFunctionID",
new SqlParameter("FunctionName",_entity.FunctionName),
new SqlParameter("FunctionHierarchy_Level",_entity.FunctionHierarchy_Level),
new SqlParameter("ControllerName", _entity.ControllerName),
new SqlParameter("ActionName", _entity.ActionName),
new SqlParameter("Function_ParentsFunctionID",_entity.Function_ParentsFunctionID)
);
But if I run this stored procedure by just calling it without parameter and of course simply stored procedure with select statement then it works and I can also see in SQL Profiler that stored procedure is called.
Working C# code
List<CreateFunctionNavigation_SP_Map> query;
query = dbContext.Database.SqlQuery<CreateFunctionNavigation_SP_Map>("exec CreateFunctionNavigation").ToList();
So I believe issue is C# class from where I am trying to call SP along with parameters. I badly stuck, tried different options but don't know what I am doing wrong. Many thanks in advance

have you tried adding commas inbetween your parameter names?
dbContext.Database.SqlQuery<CreateFunctionNavigation_SP_Map>("exec CreateFunctionNavigation #FunctionName, #FunctionHierarchy_Level, #ControllerName, #ActionName, #Function_ParentsFunctionID"
UPDATE: just checked out your stored proc code too, seen there are some issues with it.
Here is how I would change it
ALTER PROCEDURE [dbo].[CreateFunctionNavigation]
#FunctionName nvarchar(250),
#Hierarchy_Level INT,
#ControllerName nvarchar(250),
#ActionName nvarchar(250),
#Function_ParentsFunctionID INT,
#Function_identity INT OUTPUT,
#Controller_identity INT OUTPUT,
#ControllerInFunction_identity INT OUTPUT,
#Action_identity INT OUTPUT,
#ActionInFunction_identity INT OUTPUT,
#Function_ParentsFunction_identity INT OUTPUT
This puts all your outputs at the end of the function.
Right, on your c# code
var function_identity new SqlParameter() {ParameterName = "Function_identity", Direction = ParameterDirection.Output};
var controller_identity new SqlParameter() {ParameterName = "Controller_identity", Direction = ParameterDirection.Output};
var controllerInFunction_identity new SqlParameter() {ParameterName = "ControllerInFunction_identity", Direction = ParameterDirection.Output};
var action_identity new SqlParameter() {ParameterName = "Action_identity", Direction = ParameterDirection.Output};
var actionInFunction_identity new SqlParameter() {ParameterName = "ActionInFunction_identity", Direction = ParameterDirection.Output};
var function_ParentsFunction_identity new SqlParameter() {ParameterName = "Function_ParentsFunction_identity", Direction = ParameterDirection.Output};
var _result = dbContext.Database.SqlQuery<CreateFunctionNavigation_SP_Map>("exec CreateFunctionNavigation #FunctionName, #FunctionHierarchy_Level, #ControllerName, #ActionName, #Function_ParentsFunctionID, #Function_identity out, #Controller_identity out, #ControllerInFunction_identity out, #Action_identity out, #ActionInFunction_identity out, #Function_ParentsFunction_identity out",
new SqlParameter("FunctionName",_entity.FunctionName),
new SqlParameter("FunctionHierarchy_Level",_entity.FunctionHierarchy_Level),
new SqlParameter("ControllerName", _entity.ControllerName),
new SqlParameter("ActionName", _entity.ActionName),
new SqlParameter("Function_ParentsFunctionID",_entity.Function_ParentsFunctionID),
function_identity ,
controller_identity ,
controllerInFunction_identity ,
action_identity ,
actionInFunction_identity,
function_ParentsFunction_identity
);
That might get you somewhere close.

here is my answer; it is working
List<GetNewlyCreatedNavigationsFunction_SP_Map> _query;
var function_identity_out = new SqlParameter("Function_identity", SqlDbType.Int) { Direction = System.Data.ParameterDirection.Output };
var controller_identity_out = new SqlParameter("Controller_identity", SqlDbType.Int) { Direction = System.Data.ParameterDirection.Output };
var controllerInFunction_identity_out = new SqlParameter("ControllerInFunction_identity", SqlDbType.Int) { Direction = System.Data.ParameterDirection.Output };
var action_identity_out = new SqlParameter("Action_identity", SqlDbType.Int) { Direction = System.Data.ParameterDirection.Output };
var actionInFunction_identity_out = new SqlParameter("ActionInFunction_identity", SqlDbType.Int) { Direction = System.Data.ParameterDirection.Output };
var function_ParentsFunction_identity_out = new SqlParameter("Function_ParentsFunction_identity", SqlDbType.Int) { Direction = System.Data.ParameterDirection.Output };
_query = dbContext.Database.SqlQuery<GetNewlyCreatedNavigationsFunction_SP_Map>("exec CreateFunctionNavigation #FunctionName, #Hierarchy_Level, #ControllerName, #ActionName, #Function_ParentsFunctionID, #Function_identity out, #Controller_identity out, #ControllerInFunction_identity out, #Action_identity out, #ActionInFunction_identity out, #Function_ParentsFunction_identity out",
new SqlParameter("#FunctionName", _entity.FunctionName),
new SqlParameter("#Hierarchy_Level", _entity.FunctionHierarchy_Level),
new SqlParameter("#ControllerName", _entity.ControllerName),
new SqlParameter("#ActionName", _entity.ActionName),
new SqlParameter("#Function_ParentsFunctionID", _entity.Function_ParentsFunctionID),
function_identity_out,
controller_identity_out,
controllerInFunction_identity_out,
action_identity_out,
actionInFunction_identity_out,
function_ParentsFunction_identity_out
).ToList();

Related

How to query multiple result in specify value in dapper

I want return all records when data.Task = 0 in this query. how to do it?
var data = SqlConn.ConnectSQL().Query("Select TicketNo, PickName From TaxiTicket Where DriverID = #ID AND Status = #State",
new { ID = find.Account, State = data.Task });
var data = SqlConn.ConnectSQL().Query("Select TicketNo, PickName From TaxiTicket
Where DriverID = #ID AND (Status = case #State when 0 then Status else #state end)",
new { ID = find.Account, State = data.Task });
this only addresses your point of question, how you prepare and pass parameters is another issue. you seem to have some weird assignment using same data variable.

Database call throwing unexpected error in C#

I have written the following method to get a list of objects from database:
public IEnumerable<ProductDBKey6> AssignProductKey6 (string strProdList)
{
List<ProductDBKey6> lstProdDBKey6 = new List<ProductDBKey6>();
// Create the parameters collection
var parameters = new Collection<SqlParameter>();
// Add each parameter. Entity will not work without all params in the correct order
SqlParameter param = StoredProcedureParameterBuilder.StringParam("#ProductID", strProdList, -1);
int? tempTimeout = this.Database.CommandTimeout;
this.Database.CommandTimeout = 300;
lstProdDBKey6 = this.Database.SqlQuery<ProductDBKey6>("spc.FindProductDBKeyForID", param).ToList();
this.Database.CommandTimeout = tempTimeout;
return lstProdDBKey6;
}
But I am receiving the error that #ProductID parameter is not supplied. Following is the code written in StoredProcedureParameterBuilder class:
internal static class StoredProcedureParameterBuilder
{
internal static SqlParameter StringParam(string paramName, string paramValue, int paramSize)
{
SqlParameter outParam = new SqlParameter
{
ParameterName = paramName,
SqlDbType = System.Data.SqlDbType.VarChar,
Direction = System.Data.ParameterDirection.Input,
Size = paramSize
};
if (string.IsNullOrEmpty(paramValue))
{
outParam.Value = DBNull.Value;
}
else
{
outParam.Value = paramValue;
}
return outParam;
}
}
My stored procedure accepts only one parameter #ProductID. Following is the Stored Procedure declaration:
ALTER PROCEDURE [spc].[FindProductDBKeyForID] (
#ProductID VARCHAR(MAX)
)
Please help how to resolve the error.
Instead of this line:
lstProdDBKey6 =
this
.Database.SqlQuery<ProductDBKey6>("spc.FindProductDBKeyForID", param)
.ToList();
Try this:
lstProdDBKey6 =
this
.Database.SqlQuery<ProductDBKey6>("exec spc.FindProductDBKeyForID #ProductID", param)
.ToList();

parameter value passsing in c# asp.net

I have got 2 asp pages. Firstly i get logged in through log in page and 2nd page is home page where i got few buttons of some tasks. Along with that i got user details which consists of FULLNAME,ADDRESS,CELL NUMBER,BLOOD GROUP and EMAILID, this should be displayed dynamically in their particular labels from DATABASE once the user logs in using his username and password.
I have written Query for this within the GetLoginDetails Stored Procedure. I have to display Employee Name,his Last Login Date,Time etc. once his log in and enters home page in the same way i should get user details.
ALTER PROCEDURE [dbo].[GetLastLogin]
#LoggedInUser nvarchar(50),
#FullName nvarchar(50),
#Address nvarchar(50),
#MobileNumber bigint,
#EmailID nvarchar(50),
#BloodGroup nvarchar(50),
#EmpName nvarchar(50)
As
Declare #LastLogin int
Set #LastLogin = (Select MAX(AccessID)from dbo.ACCESS_INFO where Flag = 1)
Select Access_Date, Access_Time from dbo.ACCESS_INFO where LoggedInUser = #LoggedInUser and AccessID = #LastLogin
Update dbo.EmployeeData
Set Empname = #EmpName
where FullName = #FullName and Address = #Address and MobileNumber = #MobileNumber and EmailID = #EmailID and BloodGroup = #BloodGroup ;
im getting error saying tht ("Procedure or function 'GetLastLogin' expects parameter '#FullName', which was not supplied.") please help me out
back end code
protected void Page_Load(object sender, EventArgs e)
{
if (Session["Username"] != null)
{
try
{
MTMSDTO objc = new MTMSDTO();
LblLogdInUser.Text = Session["EmpName"].ToString();
LblUser.Text = Session["Username"].ToString();
objc.LoggedInUser = LblUser.Text;
DataSet laslogin = obj.GetLastLogin(objc);
DataView LasLogin = new DataView();
LasLogin.Table = laslogin.Tables[0];
GrdLasLogin.DataSource = LasLogin;
GrdLasLogin.DataBind();
if (!IsPostBack)
{
int lastlog = GrdLasLogin.Rows.Count;
if (lastlog == 0)
{
LblLastLoginD.Text = "This is your First Login";
DateTime today = System.DateTime.Now.Date;
LblToday.Text = today.ToString();
LblTime.Text = System.DateTime.Now.ToLongTimeString();
objc.LoggedInUser = LblLogdInUser.Text;
objc.AccessDate = Convert.ToDateTime(LblToday.Text);
objc.AccessTime = Convert.ToDateTime(LblTime.Text);
objc.AccessStatus = "New Login";
objc.AccessFlag = 1;
int accessinfo = obj.InsertAccessInfo(objc);
}
else
{
LblLastLoginD.Text = Convert.ToDateTime(GrdLasLogin.Rows[0].Cells[0].Text).ToString("dd/MMM/yyyy");
LblLastLoginT.Text = GrdLasLogin.Rows[0].Cells[1].Text;
DateTime today = System.DateTime.Now.Date;
LblToday.Text = today.ToString();
LblTime.Text = System.DateTime.Now.ToLongTimeString();
objc.LoggedInUser = LblLogdInUser.Text;
objc.AccessDate = Convert.ToDateTime(LblToday.Text);
objc.AccessTime = Convert.ToDateTime(LblTime.Text);
objc.AccessStatus = "New Login";
objc.AccessFlag = 1;
int accessinfo = obj.InsertAccessInfo(objc);
}
LblFname.Visible = true;
LblAdd.Visible = true;
LblMnum.Visible = true;
LblMailID.Visible = true;
LblBGroup.Visible = true;
}
}
catch (Exception ex)
{
Response.Redirect("ERROR.aspx");
Session.Abandon();
}
}
else
{
Response.Redirect("~/Login.aspx");
}
Response.CacheControl = "no-cache";
}
The error message makes it clear that you need to supply values for the parameter FullName. So, if you aren't already doing that, then go do that. The only complication here is null values; a string can be null, but to specify that in ADO.NET you need to pass DBNull.Value; if you use null the parameter is not included. This means you end up with code like:
cmd.Parameters.AddWithValue("FullName", (object)fullName ?? DBNull.Value);
Ugly, but it works.
Alternatively, many helper utilities will do this for you. So with "dapper":
var lastAccess = conn.Query<AccessInfo>("GetLastLogin",
new { LoggedInUser = cn, FullName = fullName, /* snipped */ },
commandType: CommandType.StoredProcesdure).FirstOrDefault();
The problem is not in your SQL. It's in your calling function in asp. You are not sending the fullname parameter to SQL server correctly. Check out this question for an example on how to send parameters.
Call a stored procedure with parameter in c#

Use a stored procedure in entity framework

I have a model-first EF model. I just imported the first stored procedure: cpas_POIDVendorProjectDate
I imported it as a function. It has three input parameters: #ProjectID(int), #VendorID(int), and #Workdate(datetime), and returns #POID(int).
Here's the SQL code:
CREATE PROCEDURE [dbo].[cpas_POIDVendorProjectDate]
#VendorID int,
#ProjectID int,
#WorkDate datetime,
#PO_ID int OUTPUT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #RowCount int;
SELECT #PO_ID = ID FROM tblPO WHERE
VendorID = #VendorID
AND ExpirationDate >= #WorkDate
AND (ProjectID IS NULL OR ProjectID = #ProjectID)
AND CapitalExpense = (
SELECT CapitalExpense FROM tblProjects WHERE ID=#ProjectID)
AND GroupCode in (1,3,5);
SET #RowCount = ##RowCount;
IF (#RowCount != 1)
SET #PO_ID = -1*#RowCount;
END
I called it in my c# program as follows:
context.cpas_POIDVendorProjectDate(
currVendorID, currProjectID, currWorkDate, currPOID);
Intellisense says my use of "context" is wrong...It's a "variable", and I'm using it as a "method".
In addition, currPOID is rejected because it's looking for a system.data.objects.OjbectParameter, not an int. Intellisense is happy with the function name and other parameters (strangely...)
What am I doing wrong here?
You can always do this if nothing else works:
using(var context = new MyDataContext())
{
using(var cmd = context.Database.Connection.CreateCommand())
{
cmd.CommandText = "cpas_POIDVendorProjectDate";
cmd.CommandType = CommandType.StoredProcedure;
//if the stored proc accepts params, here is where you pass them in
cmd.Parameters.Add(new SqlParameter("VendorId", 10));
cmd.Parameters.Add(new SqlParameter("ProjectId", 12));
cmd.Parameters.Add(new SqlParameter("WorkDate", DateTimw.Now));
var poid = (int)cmd.ExecuteScalar();
}
}
If you would like an object orientated way, then 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?

The EntitySet 'sproc_Forums_GetForumGroupByID' is not defined in the EntityContainer

I get this error after I've imported a stored procedure then create a complex type and name the function import "sproc_Forums_GetForumGroupByID" this procedure gets a single forum from a ObjectDataSource once the GridView is selected. I get the error on the line of the ExecuteReader. I already have one stored procedure working with the entity framework and it works perfectly I don't understand whats going wrong when I started my second procedure
The EntitySet 'sproc_Forums_GetForumGroupByID' is not defined in the EntityContainer 'CMSEntities'. Near simple identifier, line 1, column 13.
public class Forums
{
public Forum GetForumGroup(int ForumGroupID)
{
using (EntityConnection conn = new EntityConnection("name=CMSEntities"))
{
conn.Open();
EntityCommand cmd = new EntityCommand("CMSEntities.sproc_Forums_GetForumGroupByID", conn);
cmd.Parameters.AddWithValue("ForumGroupID", ForumGroupID);
using (EntityDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
/*
Forum forum = null;
int forumID = (int)reader[0];
string addedBy = reader[1].ToString();
DateTime addedDate = (DateTime)reader[2];
string title = reader[3].ToString();
string updatedBy = reader[4].ToString();
DateTime updatedDate = (DateTime)reader[5];
bool active = (bool)reader[6];
forum = new Forum(forumID, addedBy, addedDate, title, "", 0, 0, false, "",
updatedBy, updatedDate, active, "", 0, "", DateTime.Now, "");
return forum;*/
}
return null;
}
}
}
Verify that the sp exists in the database.
Update the entity model.
use 'Import Function' in your model browser to import stored procedure.
As a sidenote, I usually use my stored procedures as following.
IMO it's simpler than using EntityDataReader.
public Forum GetForumGroup(int forumGroupID)
{
using(CMSEntities cmsContext = new CMSEntities())
{
var forum = cmsContext.sproc_Forums_GetForumGroupByID(forumGroupID);
//...
}
}

Categories