Cascading delete for EF sqlite database tables

64 Views Asked by At

Could someone help me with writing the proper code for DeleteBehavior.ClientCascade please. I have the two classes Account and Schedule defined as follow (Account can have many Schedule objects):

 public class Account : IdentityUser
        { 
            public string Title { get; set; }
            public string FirstName { get; set; }
            public string LastName { get; set; }
    
            public List<Schedule> Schedules { get; set; }
        }
        public class Schedule
        {
                public string AccountAccountId { get; set; }
                public int ScheduleId { get; set; }
                public DateTime Date { get; set; }
        }

... and the context

     public class DataContext : IdentityDbContext<Account>
        {
            public DbSet<Account> Accounts { get; set; }
            public DbSet<Schedule> Schedules { get; set; }
            public DataContext(IConfiguration configuration, DbContextOptions options) : base(options)
            {
                Configuration = configuration;
            }
    
            protected override void OnConfiguring(DbContextOptionsBuilder options)
            {
                // connect to sqlite database
                options.UseSqlite(Configuration.GetConnectionString("WebApiDatabase"));
            }
            protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                base.OnModelCreating(modelBuilder);
                //modelBuilder.Entity<Account>().HasMany(e => e.RefreshTokens).WithOne(e => e.Account).IsRequired();
    
                modelBuilder.Entity<Schedule>()
                .HasOne(b => b.Account)
                .HasMany(a => a.Schedules) <--- Error
                .OnDelete(DeleteBehavior.ClientCascade); <--- Error
            }
        }

I am following this article link but I am getting errors in my DataContext when trying to do:

modelBuilder.Entity<Schedule>()
        .HasOne(b => b.Account)<--- error
        .HasMany(a => a.Schedules) 
        .OnDelete(DeleteBehavior.ClientCascade); 
2

There are 2 best solutions below

0
Qiang Fu On

This doc is incomplete. Maybe you should try this https://www.learnentityframeworkcore.com/configuration/one-to-many-relationship-configuration first. To define a one-to-many relationship.You will need to make the Schedule class like below

    public class Schedule
    {
        public string AccountAccountId { get; set; }
        public int ScheduleId { get; set; }
        public DateTime Date { get; set; }
        public Account? Account { get;set; }
    }

Use Account? here to make foreignkey AccounId nullable.
Generally use "s" stands for "schedule" and your schedule class now has a "Account" field now. Then you could define the one-to many relationship use

            modelBuilder.Entity<Schedule>()
                .HasOne(s => s.Account)
                .WithMany(a => a.Schedules);

or

            modelBuilder.Entity<Account()
                .HasMany(a => a.Schedules)
                .WithOne(s => s.Account);

They have the same result. Must use Has.. as first behind the entity then use With. Your code actually use 2 Has... method.

The .OnDelete(DeleteBehavior.ClientCascade); could turn to be error if you hadn't add ? to Account? to make it nullable.

0
janci On

This worked for me without modifying Schedule class:

modelBuilder.Entity<Account>()
                .HasMany<Schedule>(a => a.Schedules)
                .WithOne()
                .OnDelete(DeleteBehavior.ClientCascade);