ErikEJ / erikej.github.io

ErikEJ blog

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Get a SQL Server stored procedure return value with EF Core

ErikEJ opened this issue · comments

Hi, i want to ask something about your blog "Mapping and using SQL Server stored procedures with EF Core Power Tools"
can i get more information about how to implement that code in my project, i was trying but i still not understood. And was go to your commit url https://github.com/ErikEJ/EFCorePowerTools/blob/master/src/GUI/RevEng.Core/DbContextExtensions, but i don't understand how to use that method. Can you explain more for me.

Note : i use .NET 5.0 with Microsoft.EntityFrameworkCore v 5.0.0

Thank

@DangerZombie Have you tried running the tool and generating the code, that should give you some idea?

HI @ErikEJ, i was trying your tool and generating the code but i still confuse. I using your code and implement in my project, when i try to get data from SQL Server with Stored Procedure, i use offset and fetch next to paging data, that not return any value. Have an idea for that? And i have a additional question, why the function using async type?

Please provide some code.

public async Task<GetCityPagedResult[]> GetCityPaged(int? Offset, int? FetchRow, Guid? CountryID, OutputParameter returnValue = null)
{
var parameterOffset = new SqlParameter
{
ParameterName = "Offset",
Value = Offset ?? Convert.DBNull,
SqlDbType = System.Data.SqlDbType.Int,
};

        var parameterFetchRow = new SqlParameter
        {
            ParameterName = "FetchRow",
            Value = FetchRow ?? Convert.DBNull,
            SqlDbType = System.Data.SqlDbType.Int,
        };

        var parameterCountryID = new SqlParameter
        {
            ParameterName = "CountryID",
            Value = CountryID ?? Convert.DBNull,
            SqlDbType = System.Data.SqlDbType.UniqueIdentifier,
        };

        var parameterreturnValue = new SqlParameter
        {
            ParameterName = "returnValue",
            Direction = System.Data.ParameterDirection.Output,
            SqlDbType = System.Data.SqlDbType.Int,
        };

        var _ = await _context.SqlQuery<GetCityPagedResult>("EXEC @returnValue = [dbo].[GetCityPaged] @Offset, @FetchRow, @CountryID", parameterOffset, parameterFetchRow, parameterCountryID, parameterreturnValue);

        returnValue?.SetValue(parameterreturnValue.Value);

        return _;
    }

That code is generated by the tool

Do you need the Stored Procedure?

Yes, I was more interested in your code, and a description of what exactly is not working for you.

Essentially, I need full repro code to assist in the best way

Can I pass a class with sql parameter

@kokilasanjeewa no. A Datatable if your parameter is a TVP

Thanks

ALTER PROCEDURE [dbo].[sp_ImportPetType](
--@PetTypeLibrary AS dbo.TablePetType READONLY,
@Person_ID int = 0, --Logged in Users Employee Person_ID
@Person_Name nvarchar(MAX) = null --Logged in Users Employee Name

)
AS
BEGIN

SET NOCOUNT ON

/*
** Declarations.
*/
DECLARE @UpdateRecordsCount int = 1
DECLARE @NewRecordsCount int = 1
DECLARE @retcode int = 0

Declare @EventComment nvarchar(MAX) = ''
DECLARE @PetTypeLibrary as dbo.TablePetType

/*
** Security Check: require sysadmin
*/
--IF (ISNULL(IS_SRVROLEMEMBER('sysadmin'),0) = 0)
--BEGIN
--    RAISERROR(21089,16,-1) 
--    RETURN (0)
--END

--select @server_added = 0 
--select @login = 'distributor_admin'

/*
** INNER JOIN by ZipCode and County, and update existing records.
*/
INSERT INTO @PetTypeLibrary (Pet_Type_ID, Pet_Type_Description) 	(SELECT    PTypeSeq AS Pet_Type_ID, PTypeName AS Pet_Type_Description FROM wkennel7.dbo.PetTypes);

SET @UpdateRecordsCount = (SELECT COUNT(dbo.Pet_Type.Pet_Type_ID)
FROM dbo.Pet_Type INNER JOIN
@PetTypeLibrary PTL ON dbo.Pet_Type.Pet_Type_Description <> PTL.Pet_Type_Description AND dbo.Pet_Type.Pet_Type_ID = PTL.Pet_Type_ID)

UPDATE dbo.Pet_Type
SET dbo.Pet_Type.Pet_Type_Description = PTL.Pet_Type_Description
FROM dbo.Pet_Type INNER JOIN
@PetTypeLibrary PTL ON dbo.Pet_Type.Pet_Type_Description <> PTL.Pet_Type_Description AND dbo.Pet_Type.Pet_Type_ID = PTL.Pet_Type_ID

/* --Insert an Event Log at EventLog_YYYYMM /
SET @EventComment = 'Updated '+CONCAT(@UpdateRecordsCount,'')+ N' records in the Pet Type Database by ' + isnull(@Person_Name,SUSER_NAME()) +' on '+ convert(varchar,getdate(),22);
-- SELECT @EventComment;
EXEC @retcode = [dbo].[sp_InsertEventLog] @Person_ID, 'sp_ImportPetType UPDATED', '0',@EventComment;
/
--End Insert an Event Log at EventLog_YYYYMM */

/*
** Insert New ZipCode which do not exist in zipcodes database
*/

SET @NewRecordsCount = (SELECT COUNT(PTL.Pet_Type_ID)
FROM dbo.Pet_Type RIGHT OUTER JOIN
@PetTypeLibrary PTL ON (dbo.Pet_Type.Pet_Type_Description = PTL.Pet_Type_Description AND dbo.Pet_Type.Pet_Type_ID = PTL.Pet_Type_ID)
WHERE (dbo.Pet_Type.Pet_Type_ID IS NULL)
)

-- /*
-- ** Insert New ZipCode which do not exist in zipcodes database
-- */
INSERT INTO dbo.Pet_Type (Pet_Type_Description)
(SELECT PTL.Pet_Type_Description
FROM dbo.Pet_Type RIGHT OUTER JOIN
@PetTypeLibrary PTL ON dbo.Pet_Type.Pet_Type_Description = PTL.Pet_Type_Description AND dbo.Pet_Type.Pet_Type_ID = PTL.Pet_Type_ID
WHERE (dbo.Pet_Type.Pet_Type_Description IS NULL))

/* --Insert an Event Log at EventLog_YYYYMM /
SET @EventComment = 'Inserted '+CONCAT(@NewRecordsCount,'')+ N' records into the Pet Type Database by ' + isnull(@Person_Name,SUSER_NAME()) +' on '+ convert(varchar,getdate(),22);
-- SELECT @EventComment;
EXEC @retcode = [dbo].[sp_InsertEventLog] @Person_ID, 'sp_ImportPetType INSERTED', '0',@EventComment;
/
--End Insert an Event Log at EventLog_YYYYMM */

    Select @NewRecordsCount as NewRecordsCount, @UpdateRecordsCount as UpdateRecordsCount

END

please explain how can I get NewRecordsCount, and UpdateRecordsCount in ef core

@kokilasanjeewa what does the result shape look like?

just return NewRecordsCount, and UpdateRecordsCount as integer

image
just return NewRecordsCount, and UpdateRecordsCount as integer

@kokilasanjeewa Just use a keyless entity like:

public class SpResult()
{
    public int NewRecordsCount { get; set; }
    public int UpdateRecordsCount { get; set; }
}

I put partial class instead of class .now it's working thanks