簡體   English   中英

實體框架級聯刪除(繼承)

[英]Entity Framework Cascade Delete (Inheritance)

我已經閱讀了我能找到的所有內容,但我仍然無法解決我的問題。 我正在使用 PostgreSQL 並且我有一個抽象 class 和一個孩子 class。 我希望在刪除父級時也刪除所有相關的依賴項。

這是我的 class 的樣子:

public abstract class NotificationModel
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    public Guid id { get; set; }
    public string type { get; set; }
    // and other common fileds
    public abstract NotificationModel buildObject(JObject json);
}

我的孩子 class:

class SmsNotificationModel : NotificationModel
{
    public override NotificationModel buildObject(JObject json){return dummyObj;}
    public SmsBody Body { get; set; }
    public Guid Fk_sms { get; set; }
}

和短信正文

class SmsBody
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    public Guid Id { get; set; }
    public List<string> Recipients { get; set; }
    public string Route { get; set; }

    //edit
    public SmsNotificationModel smsNotModel { get; set; }
}

在 DbContext 中:

 protected override void OnModelCreating(ModelBuilder modelBuilder)
 {
        modelBuilder.Entity<SmsNotificationModel>()
            .HasOne(em => em.Body)
            .WithOne(d => d.smsNotModel)
            .HasForeignKey<SmsNotificationModel>(f => f.Fk_sms)
            .OnDelete(DeleteBehavior.Cascade);

        base.OnModelCreating(modelBuilder);
  }

我不明白我做錯了什么。 該表被標記為級聯,但是當我嘗試刪除它時它根本不起作用。 有人可以給我一些關於如何設置它的提示。

==== 稍后編輯

我有一個用於刪除的通用存儲庫(模板參數是 NotificationModel 抽象類)

public class GenericRepository<T> : IGenericRepository<T> where T :class
{
    private readonly ApplicationDbContext _context;
    private DbSet<T> table = null;

    public GenericRepository(ApplicationDbContext _context) {
        this._context = _context;
        table = _context.Set<T>();
    }

    public void Delete(object id){
        T existing = table.Find(id);
        table.Remove(existing);
    }
}

應用於后期場景的一對一關系配置。
實體定義。

短信通知

public class SmsNotificationModel : NotificationModel
{
    public SmsBody Body { get; set; }
    // ...
}

短信正文

public class SmsBody
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    public Guid Id { get; set; }
    // ...

    // I moved the Id relation here.
    // To me, it seems like Notification is the one-level-up absatraction model.
    // This may be changed at any time.
    public SmsNotificationModel SmsNotModel { get; set; }
    public Guid SmsNotificationModelId { get; set; }
}

另外,順便說一下,我public了課程。 我不確定這是否重要,因為我相信實體框架需要從它自己的程序集訪問我們的程序集。

然后,配置OnModelCreating

public class YourContext : DbContext
{
    // ...

    public DbSet<SmsNotificationModel> Notifications { get; set; }
    public DbSet<SmsBody> SmsBodies { get; set; }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        // ...

        builder.Entity<SmsNotificationModel>(entity =>
        {
            // Configures the One-To-One relationship
            // and the OnDelete behavior, as well.
            entity.HasOne<SmsBody>(notification => notification.Body)
                  .WithOne(body => body.SmsNotModel)
                  .HasForeignKey<SmsBody>(body => body.SmsNotificationModelId)
                  .OnDelete(DeleteBehavior.Cascade);
        });
    }
}

而且,只是為了完成,數據訪問層。
我不知道通用約束是否符合實體框架策略。 我相信如果有。
我只想提一下我通往 go 的方式。

public interface IRepository<TEntity> : IDisposable
{
    // CRUD methods...

    void Delete(TEntity entity);
    void Delete(Expression<Func<TEntity, bool>> expression);

    void Save();
}

我喜歡有一個定義所有 CRUD 操作的接口。 甚至是定義相同操作但異步的IAsyncRepository

public class SmsRepository : IRepository<SmsNotificationModel>
{
    private readonly YourContext _context;

    public SmsRepository(YourContext context) =>  _context = context;

    // CRUD operations implementation ...

    public void Delete(SmsNotificationModel entity)
    {
        _context.Notifications.Remove(entity);
    }
}

如果您遇到任何問題,您可以繼續閱讀擴展說明

希望能幫助到你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM