Rizwan
Rizwan

Reputation: 89

How to correctly set up one-to-zero-or-one relationship in EF Core?

I am trying to set up 1 to 0 or 1 relationship with ondelete cascade in EF Core 3.1.

This is an extension of IdentityUser(Principle entity) that has to have (optional/nullable)FbUser property.

 public class PtUser : IdentityUser<int>
    {
        [PersonalData]
        [Column(TypeName = "nvarchar(100)")]
        public string FirstName { get; set; }


        [PersonalData]
        [Column(TypeName = "nvarchar(100)")]
        public string LastName { get; set; }

        public FbUser FbUser { get; set; }

    }
 public class FbUser
    {
        [Key]
        [Required]
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public string FbUserId { get; set; }

        public string Name { get; set; }

        public string FbEmail { get; set; }
        
        public PtUser PtUser { get; set; }

        public int PtUserId { get; set; }
    }

How can I configure it in such a way that if PtUser has linked their Facebook account, their FbUser.FbUserId becomes the foreign key in PtUsers table and when that PtUser is deleted this deletion is cascaded to the associated FbUsers table row.

 public class PtDbContext : IdentityDbContext<PtUser, PtRole, int>
    {
        public PtDbContext(DbContextOptions<PtDbContext> options)
            : base(options)
        {
        }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            builder.Entity<PtUser>()
               .HasOne(a => a.FbUser)
               .WithOne(b => b.PtUser)
               .HasForeignKey<FbUser>(b => b.PtUserId)
               .OnDelete(DeleteBehavior.Cascade);
        }

        public DbSet<FbUser> FbUsers { get; set; }
    }

Upvotes: 0

Views: 168

Answers (1)

juunas
juunas

Reputation: 58733

You can set that it is not required to make it 1 to 0-1:

builder.Entity<PtUser>()
    .HasOne(a => a.FbUser)
    .WithOne(b => b.PtUser)
    .IsRequired(false)
    .HasForeignKey<FbUser>(b => b.PtUserId)
    .OnDelete(DeleteBehavior.Cascade);

We use pretty much this definition for one of the relations in our model. The main difference is that we defined the relation from the direction of the dependent entity, i.e. FbUser in your case, so something like:

builder.Entity<FbUser>()
    .HasOne(a => a.PtUser)
    .WithOne(b => b.FbUser)
    .IsRequired(false)
    .HasForeignKey(a => a.PtUserId)
    .OnDelete(DeleteBehavior.Cascade);

Upvotes: 1

Related Questions