1
votes

EF Core ExecuteSqlCommandAsync: la conversion a échoué lors de la conversion de la valeur nvarchar '1,2' en type de données int

J'exécute l'exécution de SQL brut pour supprimer certains enregistrements que j'ai ajoutés pour le test. Si j'exécute la même requête dans le studio de gestion, cela fonctionne bien, mais lorsque j'exécute cette requête EF Core 2.0, elle renvoie l'erreur ci-dessous

var idList = await Context.User.ToListAsync();
var ids = string.Join(",",idList.Select(x=>x.Id));
await _context.Database.ExecuteSqlCommandAsync($"Delete from User where Id in ({ids}) and RoleId = {contact.RoleId}");

Code

System.Data.SqlClient.SqlException: 'Conversion failed when converting the nvarchar value '1,2' to data type int.'

Exécution de la requête Supprimer de sale.WatchList où OfferId dans (1,2) et UserId = 9

Est-ce que quelqu'un pourrait s'il vous plaît indiquer ce qui ne va pas avec le code ci-dessus.

Merci


1 commentaires

Une seule chaîne contenant des virgules n'est pas la même chose que plusieurs chaînes (ou plusieurs entiers) séparés par des virgules. Aussi vrai en SQL que dans la plupart des autres langages.


3 Réponses :


3
votes

EF Core transformera les chaînes interpolées en requêtes avec des paramètres pour créer des requêtes réutilisables et se protéger contre les vulnérabilités d'injection SQL. Voir: Requêtes SQL brutes - EF Core - Passing Paramètres

Donc

   Delete from User where Id in (@ids) and RoleId = @RoleId

est transformé en

$"Delete from User where Id in ({ids}) and RoleId = {contact.RoleId}"

Avec SqlParameters lié.

Si ce n'est pas ce que vous voulez, créez simplement la requête SQL sur une ligne précédente.


1 commentaires

bien que cela crée un avertissement



1
votes

Cela ne fonctionnera pas. Vous devez écrire une requête dynamique. Veuillez essayer comme ci-dessous un

var idList = await _dataContext.User.ToListAsync();
            var ids = string.Join(",", idList.Select(x => x.Id));
            await _dataContext.Database.ExecuteSqlCommandAsync($"execute('Delete from User where Id in ({ids}) and RoleId = {contact.RoleId}')");


1 commentaires

renvoie une erreur: Doit déclarer la variable scalaire "@ p0".



0
votes

Bien que la réponse acceptée fonctionne, elle crée beaucoup d'avertissements, donc pour l'instant j'utilise ce que @Abu Zafor a suggéré avec un petit changement / correction

wait _dataContext.Database.ExecuteSqlCommandAsync ($ "execute ('Delete from User where Id in ({ids}) and RoleId = {contact.RoleId}')", ids, contact.RoleId);


0 commentaires