Stored procedure not detecting change in database in Blazor server - c#

Here I have a stored procedure dbo.sp_GetChatMessages which returns all columns that is DualMessageId,SenderName,ReceiverName,MessageBody,SendOn,IsSeen column value from table DualMessage.
Now the problem is that if I make any changes to any of the column of DualMessage table and then call the procedure from my service, then the procedure returns same old the value which are before making any changes, that is it does not return that new changed value but running the same procedure in SQL Server Management Studio (SSMS) works fine and gives the changed value.
Below is how I call my procedure in service
public class MainService
{
public BlazorDBContext db = new BlazorDBContext();
public List<DualMessage> GetAllChatMessagesToDisplay(string loggedinUserName)
{
SqlParameter param1 = new SqlParameter("#loggedInUserName", loggedinUserName);
var messagesList = db.DualMessage.FromSqlRaw("EXECUTE dbo.sp_GetChatMessages #loggedInUserName", param1).ToList();
return messagesList;
}
}
Below is stored procedure
ALTER PROCEDURE [dbo].[sp_GetChatMessages] (#loggedInUserName nvarchar(500))
AS
SELECT *
FROM (
SELECT
DualMessageId, SenderName, ReceiverName, MessageBody, SendOn, IsSeen,
ROW_NUMBER() OVER(
PARTITION BY
concat(#loggedInUserName, CASE WHEN senderName =#loggedInUserName
THEN receiverName
ELSE senderName END )
ORDER BY sendOn DESC ) AS rn
FROM DualMessage
WHERE senderName=#loggedInUserName
OR receiverName=#loggedInUserName) as msg
WHERE
msg.rn=1
ORDER BY DualMessageId DESC;

Related

How to return results from stored procedure as a List?

Previously this worked well and recently the line stop working. This code uses the DB context to run a procedure and return it in List format. For some reason I am not seeing the error, I just see the action fail because it is not executing.
I ran the stored procedure in SQL Server and see the desired results, just not seeing it happening from the application layer.
[Http.Route("postsearch")]
public async Task<IHttpActionResult> PostSearch(SearchInputDTO srequest)
{
var searchString = srequest.SearchValue.ToString();
List<output> seResult = new List<output>(_output.searchLog(searchString)); /*This line stopped working*/
return Ok(seResult);
}
Stored procedure:
SET FMTONLY OFF
GO
SET NOCOUNT ON
GO
ALTER PROCEDURE [dbo].[searchLog]
#searchValue VARCHAR(150)
AS
SELECT *
FROM [dbo].[output]
WHERE CONTAINS (*, #searchValue)
Implementation in Entity Framework
public virtual int searchLog(string searchValue)
{
var searchValueParameter = searchValue != null ?
new ObjectParameter("searchValue", searchValue) :
new ObjectParameter("searchValue", typeof(string));
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("searchLog", searchValueParameter);
}
This should return the rows from the query.
The Solution I found was to modify the output of the stored procedure in Visual Studio.
Try removing the new instance of the list and just have it like this
List<output> seResult = _output.searchLog(searchString);
Update stored proc to
#searchValue varchar(150)
AS
BEGIN
SELECT
[ColumnName1]
,[ColumnName2] ...etc...
FROM [dbo].[output]
WHERE CONTAINS (*,#searchValue)
END

EF6 stored procedure must declare scalar variable

I am trying to call a stored procedure using C# EF6 to bring back data. I have tried to run the stored procedure in SQL management studio and it seems to work fine, however when I try to run it in my application I get an error saying "Must declare the scalar variable "#devID"
Here is part of my method in my application calling the stored procedure
public IHttpActionResult GetMetrics(int deviceID, string attribute, string startDate)
{
if (deviceID == 0)
{
return NotFound();
}
var metrics = db.Database.SqlQuery<Metrics>("GetMetrics #devID, #MetricType, #startTime", deviceID, attribute, startDate).ToList();
and here is my stored procedure:
ALTER PROCEDURE [dbo].[GetMetrics]
-- Add the parameters for the stored procedure here
#devID int,
#MetricType nvarchar(20),
#startTime nvarchar(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT *
FROM dbMetrics
WHERE deviceID = #devID and MetricType = #MetricType and timeStamp >= #startTime
ORDER BY timeStamp
END
As per the documentation, if you want to use named parameters, you need to pass SqlParameter objects like this:
var metrics = db.Database.SqlQuery<Metrics>("GetMetrics #devID, #MetricType, #startTime",
new SqlParameter("devID", deviceID),
new SqlParameter("MetricType", attribute),
new SqlParameter("startTime", startDate)
).ToList();

How to take input from SQL stored procedure to a return statement

alter procedure [dbo].[XXX]
(
#vendorworksationID uniqueidentifier ,
#sdate date,
#edate date,
#total int out
)
begin
select #total = COUNT(*)
from AdvertisedCampaignHistory a
where
CAST(a.CreationDate AS DATE) BETWEEN CAST(#sdate as DATE) AND CAST(#edate as DATE)
and a.CampaignID in (select cc.BCampaignID
from BeaconCampaign cc, VendorWorkStation vw
where cc.VendorWorkStationID = vw.VendorWorkStationID
and VendorID = #vendorworksationID)
return #total
end
The above code shows the stored procedure that return an integer value from SQL Server
ObjectParameter Output = new ObjectParameter("total", typeof(Int32));
var resBC = this.Context.getTotalSentBeaconCampaign(VendorWorkstationID, sdate,edate,Output).FirstOrDefault();
The above code shows how I am passing parameters and retrieving the value on the C# side
While running the code I am getting following error
The data reader returned by the store data provider does not have
enough columns for the query requested.
What could be the possible cause for this error?
Entity Framework cannot support Stored Procedure Return scalar values out of the box.To get this to work with Entity Framework, you need to use "Select" instead of "Return" to return back the value.
More Ref : http://www.devtoolshed.com/using-stored-procedures-entity-framework-scalar-return-values

get list from table using stored procedure entity framework

I am using same stored procedure for inserting and fetching data on condition base.
Stored Procedure-
ALTER PROCEDURE dbo.sp_SaveUserRole
#company_name nvarchar(50)=null,
#address nvarchar(250)=null,
#mobileno int =0,
#phoneno int=0,
#faxno int=0,
#email nvarchar(250)=null,
#regno int=0,
#establish_date datetime=null,
#cond int=0
AS
if(#cond=1)
begin
insert into Company (company_name,address,mobileno,phoneno,faxno,regno,email,establish_date) values (#company_name,#address,#mobileno,#phoneno,#faxno,#regno,#email,#establish_date)
end
else if(#cond=2)
begin
select * from company where isactive = 'True';
end
RETURN
As on inserting data using entity framework I am doing this-
public ActionResult SaveRole(CompanyModel cmp)
{
var company_name = cmp.Company_Name;
var regno = cmp.regNo;
var mobileno = cmp.mobileNo;
var phoneno = cmp.phoneNo;
var establish_date = cmp.establish_Date;
var email = cmp.emaiL;
var address = cmp.Address;
var faxno = cmp.faxNo;
db.sp_SaveUserRole(company_name, address, mobileno, phoneno, faxno, email, regno, establish_date,1);
return Json(new { success = true });
Note-
Here condition is 1 so it goes to insert data procedure.
Trying to get a list-
var list = db.sp_SaveUserRole("", "", 0, 0, 0, "", 0, null, 2).ToList();
I tried this way of getting data from table, where I had to pass necessary arguments to this procedure call. Though I wanted to go this procedure only to 2nd condition I've mentioned there.
So only for this 2nd condition How can I modify this procedure without passing arguments?
Instead of using a stored procedure I would add your company table as an entity in your edmx and access it in code.
That way instead of passing #Cont=2 to a stored proc you can instead use LINQ to access the data you require as the SQL seems very basic.
You can then remove that piece of SQL from your stored proc as mixing Inserts with selects doesnt feel right.
e.g.
// For insert
if (cont == 1)
{
// Call your stored proc here
// or if you add the company table to EF you can use the Insert use the Add
// e.g. Rough Example
_yourEntities.Companies.Add(cmp);
// Update the DB
_yourEntities.SaveChanges();
}
else
{
var companies = _yourEntities.Companies.Where(c => c.isactive == 'True');
}
If this solution is not an option i would still look to split the stored procs into two to make life easily.
Ideally though as you using Entity Framework and are looking to insert and select from a single table you get this functionality for free when you add the Company table as a entity in EF.

Access stored procedure value with LINQ. Entity Framework 5, DB first

My stored procedure is working correctly. However, I am not able to retrieve it.
My current function to retrieve the value from the stored procedure is:
public static int GetCsStatus()
{
using (Entities db = new Entities())
{
System.Data.Objects.ObjectParameter s = new System.Data.Objects.ObjectParameter("Status", typeof(int));
int r = db.proc_CsStatus(120, s);//.ToString());
return r;
}
}
I don't mind if this is changed or not used at all. I am currently getting a "r" value of -1 when I am expecting a 0 or 1.
Here is my stored procedure:
USE [DATABASE_CS]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[proc_CsStatus]
-- Add the parameters for the stored procedure here
#TimeLimit Int,
#Status Int OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON
-- Declare variables.
DECLARE #LastUpdate Int
-- Calculate the LastUpdate.
SELECT #LastUpdate = DATEDIFF(second, Timestamp, CURRENT_TIMESTAMP)
FROM Heartbeat
WHERE Id=1
-- Compare it to the TimeLimit.
IF #LastUpdate > #TimeLimit SELECT #Status = 0
ELSE SELECT #Status = 1
END
GO
Any input is much appreciated!!!
After executing your procedure, your the ObjectParameter s will contain the value. Your procedure call will not return it. The value you are looking for should be able to be found in s.Value.
Try the following:
public static int GetCsStatus()
{
using (Entities db = new Entities())
{
System.Data.Objects.ObjectParameter s = new System.Data.Objects.ObjectParameter("Status", typeof(int));
int r = db.proc_CsStatus(120, s);
return (int)s.Value;
}
}
The value which you are returning(r) is the number of rows affected by your procedure.
More Info:
Behind the scenes, your procedure is doing something along the lines of the following:
return base.ExecuteFunction("proc_CsStatus", input, output);
ObjectContext.ExecuteFunction() returns the number of rows affected by the call.

Categories