ALTER PROCEDURE [dbo].[SearchMovies]
--@Year int = null,
@CategoryIds varchar(50) = null,
@Keywords nvarchar(4000) = null,
@PageIndex int = 1,
@PageSize int = 2147483644,
@TotalRecords int = null OUTPUT
As ...
Répertoire EF:
public class EFRepository<T> : IRepository<T> where T : BaseEntity
{
private readonly ApplicationDbContext _ctx;
private DbSet<T> entities;
string errorMessage = string.Empty;
public EFRepository(ApplicationDbContext context)
{
this._ctx = context;
entities = context.Set<T>();
}
...
public IQueryable<T> ExecuteStoredProcedureList(string commandText, params object[] parameters)
{
_ctx.Database.ExecuteSqlCommand(commandText, parameters);
return entities.FromSql(commandText, parameters);
}
}
J'appelle ça comme:
var pCategoryIds = new SqlParameter()
{
ParameterName = "@CategoryIds",
Value = commaSeparatedCategoryIds,
DbType = DbType.String
};
var pKeywords = new SqlParameter()
{
ParameterName = "@Keywords",
DbType = DbType.String,
Value = name
};
var pPageIndex = new SqlParameter()
{
ParameterName = "@PageIndex",
DbType = DbType.Int32,
Value = pageIndex
};
var pPageSize = new SqlParameter()
{
ParameterName = "@PageSize",
DbType = DbType.Int32,
Value = pageSize
};
var pTotalRecords = new SqlParameter();
pTotalRecords.ParameterName = "@TotalRecords";
pTotalRecords.Direction = ParameterDirection.Output;
pTotalRecords.DbType = DbType.Int32;
var query1 = _ctx.Database.ExecuteSqlCommand("dbo.[SearchMovies] " +
"@CategoryIds, @Keywords, @PageIndex, @PageSize, @TotalRecords OUTPUT",
pCategoryIds, pKeywords, pPageIndex, pPageSize, pTotalRecords);
var query2 = _ctx.Set<MovieItem>.FromSql("dbo.[SearchMovies] " +
"@CategoryIds, @Keywords, @PageIndex, @PageSize, @TotalRecords OUTPUT",
pCategoryIds, pKeywords, pPageIndex, pPageSize, pTotalRecords);
query1
obtient la sortie pTotalRecords
fine, mais aucune valeur de retour, et le second query2
obtient les valeurs de retour mais aucun paramètre de sortie.
Dans EF 6, nous avions l'habitude d'utiliser SqlQuery
pour effectuer les deux actions en une seule commande. Comment puis-je faire la même chose dans EF core?
MIS &AGRAVE; JOUR:
Temporairement, je lance 2 requêtes, une pour obtenir le paramètre de sortie et une pour le jeu de résultats.
public IQueryable<T> ExecuteStoredProcedureList(string commandText, params object[] parameters)
{
_ctx.Database.ExecuteSqlCommand(commandText, parameters);
return entities.FromSql(commandText, parameters);
}
J'ai fait quelque chose comme ça: -
- Ma procédure stockée:
CREATE PROCEDURE p1
AS
BEGIN
RETURN 29
END
GO
Code C #
SqlParameter[] @params =
{
new SqlParameter("@returnVal", SqlDbType.Int) {Direction = ParameterDirection.Output}
};
_stagingContext.Database.ExecuteSqlCommand("exec @returnVal=" + storedProcName, @params);
var result = @params[0].Value; //result is 29
J'espère que cela t'aides
Je travaille à convertir du code EF6 en EF Core et j'ai rencontré le même problème. Dans Microsoft.EntityFrameworkCore version 2.1.0, l'utilisation suivante de FromSql()
renvoie un ensemble de résultats et définit le paramètre de sortie. Vous devez utiliser .ToList()
pour forcer le proc à s'exécuter immédiatement, renvoyant ainsi les résultats et le paramètre de sortie.
Voici un exemple de ma classe DbContext:
private DbQuery<ExampleStoredProc_Result> ExampleStoredProc_Results { get; set; }
public IEnumerable<ExampleStoredProc_Result> RunExampleStoredProc(int firstId, out bool outputBit)
{
var outputBitParameter = new SqlParameter
{
ParameterName = "outputBit",
SqlDbType = SqlDbType.Bit,
Direction = ParameterDirection.Output
};
SqlParameter[] parameters =
{
new SqlParameter("firstId", firstId),
outputBitParameter
};
// Need to do a ToList to get the query to execute immediately
// so that we can get both the results and the output parameter.
string sqlQuery = "Exec [ExampleStoredProc] @firstId, @outputBit OUTPUT";
var results = ExampleStoredProc_Results.FromSql(sqlQuery, parameters).ToList();
outputBit = outputBitParameter.Value as bool? ?? default(bool);
return results;
}
Le proc stocké renvoie l'entité suivante:
public class ExampleStoredProc_Result
{
public int ID { get; set; }
public string Name { get; set; }
}
Voici le proc stocké:
CREATE PROCEDURE ExampleStoredProc
@firstId int = 0,
@outputBit BIT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SET @outputBit = 1;
SELECT @firstId AS [ID], 'first' AS [NAME]
UNION ALL
SELECT @firstId + 1 AS [ID], 'second' AS [NAME]
END
GO
Espérons que toute personne rencontrant ce message à l'avenir le trouve utile.