J'ai un procédure stockée dans Sql Server 2017 qui prend trois paramètres.
CREATE PROCEDURE UpdateRestaurantInformation
@restaurantId nvarchar(max),
@restaurantName nvarchar(max),
@locationId int
AS
BEGIN
UPDATE Restaurants
SET RestaurantName = @restaurantName, LocationId = @locationId
WHERE RestaurantId = @restaurantId;
SELECT * FROM Restaurants WHERE RestaurantId = @restaurantId;
END
Lorsque j'ai essayé d'exécuter cette procédure stockée en utilisant l'extrait de code ci-dessous, Cela a fonctionné comme prévu.
SqlParameter param1 = new SqlParameter("@p0",restaurant.RestaurantId);
SqlParameter param2 = new SqlParameter("@p1", restaurant.RestaurantName);
SqlParameter param3 = new SqlParameter("@p2", restaurant.Location.LocationId);
var res = _context.Restaurants
.FromSqlRaw("UpdateRestaurantInformation @p0,@p1,@p2", param1, param2, param3)
.ToList();
Mais quand j'ai essayé d'utiliser FromSqlInterpolated comme ceci ci-dessous:
var res = await _context.Restaurants
.FromSqlInterpolated(
$"UpdateRestaurantInformation {restaurant.RestaurantId}, {restaurant.RestaurantName}, {restaurant.Location.LocationId}")
.SingleAsync();
Il lève cette exception:
SqlException: syntaxe incorrecte près de '@ p0'. Microsoft.Data.SqlClient.SqlCommand + <> c.b__164_0 (résultat de la tâche)
Que me trompe-je ici? S'il vous plaît, quelqu'un m'aide.
Vous pouvez apprendre à utiliser la commande sql dans ef core avec cet artical:
https://www.learnentityframeworkcore.com/raw-sql#stored-procedureshttps://www.learnentityframeworkcore.com/raw-sql#database.executesqlcommand
Comme mis à jour efcore. Vous n'avez pas besoin de construire SqlParameter dans la nouvelle API efcore.
ExecuteSqlCommandAsync et FromSql est obsolète maintenant, vous pouvez le voir dans le commentaire de code:
[Obsolete("For the async execution of SQL queries using plain strings, use ExecuteSqlRawAsync instead. For the async execution of SQL queries using interpolated string syntax to create parameters, use ExecuteSqlInterpolatedAsync instead.")]
public static Task<int> ExecuteSqlCommandAsync([NotNull] this DatabaseFacade databaseFacade, RawSqlString sql, [NotNull] IEnumerable<object> parameters, CancellationToken cancellationToken = default);
[Obsolete("For returning objects from SQL queries using plain strings, use FromSqlRaw instead. For returning objects from SQL queries using interpolated string syntax to create parameters, use FromSqlInterpolated instead. Call either new method directly on the DbSet at the root of the query.", true)]
public static IQueryable<TEntity> FromSql<TEntity>([JetBrains.Annotations.NotNull] this IQueryable<TEntity> source, [JetBrains.Annotations.NotNull] [NotParameterized] FormattableString sql) where TEntity : class
Les nouveaux apis avec params sont:
public static Task<int> ExecuteSqlInterpolatedAsync([JetBrains.Annotations.NotNull] this DatabaseFacade databaseFacade, [JetBrains.Annotations.NotNull] FormattableString sql, CancellationToken cancellationToken = default(CancellationToken))
public static IQueryable<TEntity> FromSqlInterpolated<TEntity>([JetBrains.Annotations.NotNull] this DbSet<TEntity> source, [JetBrains.Annotations.NotNull] [NotParameterized] FormattableString sql) where TEntity : class
Ces nouveaux apis utilisent FormattableString comme param, par exemple
string parm1="A";
string parm2="B";
_dbContext.Database.ExecuteSqlInterpolatedAsync($"EXEC proc @parm1={parm1},@parm2={parm2}");
@ parm1 est défini dans votre procédure de base de données, {parm1} provient de la valeur parm1 de la chaîne csharp
Détails FromSql: https://docs.Microsoft.com/en-us/ef/core/querying/raw-sql
Donc, c'est la solution que j'ai obtenue de GitHub . Tout ce que j'avais à faire était de remplacer SingleOrDefault () par ToList () comme @IvanStoev mentionné dans le commentaire.
J'ajoute simplement ceci ici si quelqu'un en a besoin à l'avenir.
var res = await _context
.Restaurants
.FromSqlInterpolated($"UpdateRestaurantInformation {restaurant.RestaurantId}, {restaurant.RestaurantName}, {restaurant.Location.LocationId}").ToListAsync();
return res.SingleOrDefault();