[英]Entity Framework Cascade Delete (Inheritance)
I have read everything that I could find and still I couldn't solve my problem.我已经阅读了我能找到的所有内容,但我仍然无法解决我的问题。 I am using PostgreSQL and I have an abstract class and a child class.
我正在使用 PostgreSQL 并且我有一个抽象 class 和一个孩子 class。 I would like that when the parent has been deleted also all related dependencies to be deleted.
我希望在删除父级时也删除所有相关的依赖项。
Here is how my class looks like:这是我的 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);
}
My child class:我的孩子 class:
class SmsNotificationModel : NotificationModel
{
public override NotificationModel buildObject(JObject json){return dummyObj;}
public SmsBody Body { get; set; }
public Guid Fk_sms { get; set; }
}
And SmsBody和短信正文
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; }
}
In DbContext:在 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);
}
I don't understand what I am doing wrong.我不明白我做错了什么。 The table is marked as a cascade but when I try to drop this it does not work at all.
该表被标记为级联,但是当我尝试删除它时它根本不起作用。 Can somebody give me some tips about how can I set up this.
有人可以给我一些关于如何设置它的提示。
==== Later Edit ==== 稍后编辑
I have a generic repo for removing (template param is NotificationModel abstract class)我有一个用于删除的通用存储库(模板参数是 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);
}
}
One-to-One Relationship configuration applied to the post scenario.应用于后期场景的一对一关系配置。
Entities definition.实体定义。
SmsNotification短信通知
public class SmsNotificationModel : NotificationModel
{
public SmsBody Body { get; set; }
// ...
}
SmsBody短信正文
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; }
}
Also, by the way, I made classes public
.另外,顺便说一下,我
public
了课程。 I am not sure if this is to important, by I believe that Entity Framework needs access from its own assembly to ours.我不确定这是否重要,因为我相信实体框架需要从它自己的程序集访问我们的程序集。
Then, configuring OnModelCreating
.然后,配置
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);
});
}
}
And, just for completion, the data-access layer.而且,只是为了完成,数据访问层。
I don't know if generic constrains fits with Entity Framework policies.我不知道通用约束是否符合实体框架策略。 I believe if does.
我相信如果有。
I just want to mention my way to go.我只想提一下我通往 go 的方式。
public interface IRepository<TEntity> : IDisposable
{
// CRUD methods...
void Delete(TEntity entity);
void Delete(Expression<Func<TEntity, bool>> expression);
void Save();
}
I like to have an interface defining all CRUD operations.我喜欢有一个定义所有 CRUD 操作的接口。 Even an
IAsyncRepository
which defines the same operations, but async.甚至是定义相同操作但异步的
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);
}
}
You can continue reading an extended explanation if you face any truobles.如果您遇到任何问题,您可以继续阅读扩展说明。
Hope it helps.希望能帮助到你。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.