是否有类似ASP.NET Core模型的OnDelete回调?

时间:2019-12-18 13:28:44

标签: c# .net-core entity-framework-core

我有以下模型:

 public class MyFiles
    {
        public int MyFilesId { get; set; }
        public string Name { get; set; }
        public string Path { get; set; }
    }

如您所知,它是上传文件的模型。每个模型都有指向wwwroot/ ...和文件名(例如图像)的路径。但是,当我删除此模型时如何删除文件?我的意思是:

var res = _applicationDbContext.MyFiles.FirstOrDefault(x => x.MyFilesId = 666);
_applicationDbContext.MyFiles.Remove(res);
_applicationDbContext.SaveChanges();

当然,以上代码不会删除文件。如果我可以这样写,那将非常有用:

 public class MyFiles
    {
        public int MyFilesId { get; set; }
        public string Name { get; set; }
        public string Path { get; set; }

        protected OnDelete() { // here is logic for removing the file from OS }
    }

3 个答案:

答案 0 :(得分:2)

在EF中没有要订阅的事件机制。不过,您可以做的是像描述here

那样覆盖SaveChanges

所描述的是以下内容的变体:

public interface IFileSystemEntity
{
      string Path { get; set; }
}

public class MyFiles: IFileSystemEntity
{
    public int MyFilesId { get; set; }
    public string Name { get; set; }
    public string Path { get; set; }

    protected OnDelete() { // here is logic for removing the file from OS }
}

然后在您的DBContext中

public override int SaveChanges()
{
    this.ChangeTracker.DetectChanges();
    var added = this.ChangeTracker.Entries()
                .Where(t => t.State == EntityState.Deleted)
                .Select(t => t.Entity)
                .ToArray();

    foreach (var entity in added)
    {
        if (entity is IFileSystemEntity)
        {
            var track = entity as IFileSystemEntity;
            // Remove logic here
        }
    }
    return base.SaveChanges();
}

答案 1 :(得分:2)

没有直接回调,但是您可以在DbContext中覆盖OnSave()并在那里调用delete方法。

public class MyFiles
{
  public int MyFilesId { get; set; }
  public string Name { get; set; }
  public string Path { get; set; }

  protected OnDelete() { // here is logic for removing the file from OS }
}

public class MyDbContext : DbContext
{
  public override int SaveChanges()
  {
    // iterate through deletions
    foreach (var item in ChangeTracker.Entries().Where(e => e.State == EntityState.Deleted))
    {
      // if item being deleted is MyFiles, call OnDelete
      if (item.Entity is MyFiles myFile)
        myFile.OnDelete();
    }

    return base.SaveChanges();
  }
}

我不知道从OS删除文件将花费多长时间,这会发生多久,以及立即删除文件有多重要。但是,如果删除文件花费时间,则添加此逻辑可能会大大降低context.SaveChanges()的调用速度。为了避免这种情况,我会考虑将“要删除的文件”添加到某种队列中,以便可以独立于dbcontext上的保存操作来处理这些文件。

答案 2 :(得分:1)

您可以覆盖方法SaveChanges()并在其中调用它以检查ChangeTracker中已删除的对象并调用回调

<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css" rel="stylesheet"/>
<div class="item-title">

  <a href="">xxxx</a>
  
  <a href="" class="item-btn-contact" title="Contattami">
    <i class="fas fa-envelope"></i>
  </a>
					
  <span class="item-type-tag">Allenatore</span>
										
</div>
<div class="item-title">

  <a href="">xxxx</a>
  
  <a href="" class="item-btn-contact" title="Contattami">
    <i class="fas fa-envelope"></i>
  </a>
										
</div>