Je travaille sur une application héritée et je suis en train de faire un appel à une procédure stockée qui retourne un entier mais je Je reçois une erreur de mappage. L'erreur lui-même est celle-ci:Obtenir paramètre de sortie de procédure stockée avec Entity Framework est de lancer une erreur de cartographie: Le lecteur de données est incompatible avec le spécifié
The data reader is incompatible with the specified IF_Insert_Incidents_Citizen'. A member of the type, 'intID', does not have a corresponding column in the data reader with the same name.
J'ai essayé de changer le nom de _intId
, sachant que Entity Framework traduit tous les noms commençant par @variable
à un _variable
.
La chose étrange est que si je fais usage LINQPad et faire un appel à la procédure stockée je reçois la valeur correcte de @intID
Ceci est la procédure stockée:
CREATE PROCEDURE [dbo].[IF_Insert_Incidents_Citizen]
@chvFolio varchar(50),
@chvOwner_Name varchar(100),
@chvOwner_Address varchar(100),
@dtsDate_Created smalldatetime,
@intUser_ID integer,
@chvDescription varchar(250),
@chvEmail varchar(50),
@intIncident_Type_ID integer,
@intIncident_Status integer,
@intID int Output
AS
SET nocount on
DECLARE @intErrorCode INT
DECLARE @intApp_ID INT
SELECT @intIncident_Type_ID = CAST(Param_Value AS INT)
FROM IF_Parameters
WHERE Param_Name = 'Citizen_Incident_Type_ID'
BEGIN
--Get an application id
INSERT INTO MasterApplication (DateCreated)
VALUES (getdate())
SELECT @intApp_ID = SCOPE_IDENTITY()
INSERT INTO IF_Incidents
(
Folio,
Owner_Name,
Owner_Address,
Date_Created,
User_ID,
Description,
Incident_Type_ID,
Incident_Status,
App_ID
)
VALUES
(
@chvFolio,
@chvOwner_Name,
@chvOwner_Address,
@dtsDate_Created,
@intUser_ID,
@chvDescription ,
@intIncident_Type_ID,
@intIncident_Status,
@intApp_ID
)
Select @intErrorCode = @@Error, @intID = SCOPE_IDENTITY()
--Insert Complaint
INSERT INTO IF_Complaints
(
Incident_ID,
Complainant_ID,
Description ,
User_ID,
Officer_Assigned_ID,
Complaint_Status_ID,
Date_Made,
Email_Complainant
)
VALUES
(
@intID,
Null,
@chvDescription + ' at ' + @chvOwner_Address,
1,
1,
1,
@dtsDate_Created ,
@chvEmail
)
Select @intErrorCode = @@Error--, @intID = SCOPE_IDENTITY()
End
Return @intErrorCode
Comme vous pouvez le voir dans la procédure stockée, le IntID obtient toujours en valeur cremental après l'insertion, appelant SCOPE_IDENTITY()
Maintenant, je suis en train d'appeler ma procédure stockée en utilisant Entity Framework de la manière suivante:
var bptRep = DependencyFactory.GetDependency<ICetRepository<IF_Insert_Incidents_Citizen>>();
var parameters = GetIfInsertIncidentsCitizenParamenters();
var res = bptRep.GetAllFromStoredProcedure(storedProcedure, parameters);
L'utilisation du référentiel de cette classe
//class with just the return value
public class IF_Insert_Incidents_Citizen
{
public int? intID { get; set; }
}
Ici, je reçois tous les paramètres de la procédure stockée
private IEnumerable<SqlParameter> GetIfInsertIncidentsCitizenParamenters()
{
// Create Parameters
var parameters = new List<SqlParameter>();
var param1 = CreateSqlParameter("@chvFolio", SqlDbType.NVarChar, ParameterDirection.Input, criteria["chvFolio"].Value, 50);
parameters.Add(param1);
....
var paramX = CreateSqlParameter("@intIncident_Status", SqlDbType.Int, ParameterDirection.Input, 10);
parameters.Add(paramX);
var outparam = CreateSqlParameter("@intID", SqlDbType.Int, ParameterDirection.InputOutput, DBNull.Value);
parameters.Add(outparam);
}
public IQueryable<TEntity>GetAllFromStoredProcedure(string storedProcedure, IEnumerable<SqlParameter> parameters)
{
var result = Context.Database.SqlQuery<TEntity>(storedProcedure, parameters).AsQueryable();
return result;
}
J'ai suivi l'approche @GertArnold suggéré, mais ne fonctionne toujours pas, ce sont mes paramètres et le code
var returnCode = new SqlParameter("@ReturnCode", SqlDbType.Int);
returnCode.Direction = ParameterDirection.Output;
var sql = "exec IF_Insert_Incidents_Citizen @chvFolio, @chvOwner_Name, @chvOwner_Address, @dtsDate_Created, @intUser_ID, @chvDescription, @chvEmail, @intIncident_Type_ID, @intIncident_Status, @intID OUT";
var data = ctx.Database.SqlQuery<object>(sql, returnCode, parameters);
var result = data.FirstOrDefault();
Regardez [ce] (https: // stackoverflow .com/a/33263793/861716) –
@GertArnold J'ai testé l'approche à partir de là, mais je me manque quelque chose, parce que ne parvient toujours pas. Je présente le OUT sur l'appel du storeprocedure et essaye celui qui fonctionne, je mets le ReturnCode aussi bien et ne fonctionne pas, je reçois d'autres erreurs – Heinrich