Delete entities without loading them into memory

不问归期 提交于 2020-01-03 07:12:12

问题


In Entity Framework Core I have the following Entity:

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

And I have a list of files ids which I need to delete:

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

How can I delete the 3 files without loading each file Content property?

_context.Files.Remove(??);

I do not want to load each file Content property as it is big in size.


回答1:


If you are sure the all Ids exist in the database and context does not contain (is not tracking) other entities with the same keys, you can use simple fake (stub) entities:

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

To avoid problem with non existing ids, you can get the existing ids from the database:

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

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

To avoid tracking entity problem, you can use the FindTracked custom extension method from my answer to Delete loaded and unloaded objects by ID in EntityFrameworkCore and combine it with any of the above.

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 }));



回答2:


You can try EntityFramework-Plus and 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();

This way Delete is committed with the transaction




回答3:


Entity tracking can work manually and without any database call, so long as you can uniquely identify the entity.

What you are after is documented here.

var entity = new EntityModel {
   Id = yourId
};

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

Which is the same as ...

var entity = new EntityModel {
   Id = yourId
};

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


来源:https://stackoverflow.com/questions/48443370/delete-entities-without-loading-them-into-memory

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!