web-dev-qa-db-fra.com

Supprimer des entités sans les charger en mémoire

Dans Entity Framework Core, j'ai l'entité suivante:

public class File {
  public Int32 Id { get; set; }
  public Byte[] Content { get; set; }
  public String Name { get; set; }
}

Et j'ai une liste d'ID de fichiers que je dois supprimer:

List<Int32> ids = new List<Int32> { 4, 6, 8 }; // Ids example

Comment puis-je supprimer les 3 fichiers sans charger chaque propriété de contenu de fichier?

_context.Files.Remove(??);

Je ne veux pas charger chaque propriété de contenu de fichier car elle est de grande taille.

15
Miguel Moura

Si vous êtes sûr que tous les ID existent dans la base de données et que le contexte ne contient pas (ne suit pas) d'autres entités avec les mêmes clés, vous pouvez utiliser de faux faux ( stub ) entités:

_context.RemoveRange(ids.Select(id => new File { Id = id }));

Pour éviter tout problème avec des identifiants non existants, vous pouvez obtenir les identifiants existants de la base de données:

var existingIds = _context.Files.Where(f => ids.Contains(f.Id)).Select(f => f.Id).ToList();

_context.RemoveRange(existingIds.Select(id => new File { Id = id }));

Pour éviter de suivre le problème d'entité, vous pouvez utiliser la méthode d'extension personnalisée FindTracked de ma réponse à Supprimer les objets chargés et déchargés par ID dans EntityFrameworkCore et la combiner avec l'une des options ci-dessus.

var existingIds = _context.Files.Where(f => ids.Contains(f.Id)).Select(f => f.Id).ToList();

_context.RemoveRange(
    existingIds.Select(id => _context.FindTracked(id) ?? new File { Id = id }));
5
Ivan Stoev

Le suivi d'entité peut fonctionner manuellement et sans appel de base de données, tant que vous pouvez identifier l'entité de manière unique.

Ce que vous recherchez est documenté ici .

var entity = new EntityModel {
   Id = yourId
};

var entry = context.Entry(entity);
entry.State = EntityState.Deleted;
context.SaveChanges();

C'est la même chose que ...

var entity = new EntityModel {
   Id = yourId
};

var entry = context.Entry(entity);
context.Remove(entry);
context.SaveChanges();
3
Ablue

Vous pouvez essayer EntityFramework-Plus et Database.BeginTransaction()

var db = new YourDbContext();
var dbContextTransaction = db.Database.BeginTransaction();
ctx.Users.Where(x => x.LastLoginDate < DateTime.Now.AddYears(-2)).Delete();
//some other DB actions 
db.SaveChanges();
dbContextTransaction.Commit();

De cette façon, Delete est validé avec la transaction

0
Toolkit