Use the Best Practice for Relation Delete in EF Core

c# entity-framework entity-framework-core

Question

I have 2 tabel in database : User and User Role and they are have one to many relation.

User => public ICollection<UserRole> UserRoles { get; set; }

UserRole => public User User { get; set; }

now i need to delete User and then Delete it Role in UserRole .

i write this code :

 public async Task<ReturnResult> DeleteUser(DeleteDto deleteDto, CancellationToken cancellationToken)
    {
        var user = userManager.Users.Include(x => x.UserRoles).FirstOrDefault(c => c.Id == deleteDto.id);
        user.UserRoles.Remove(user.UserRoles.OrderBy(c => c.UserId).FirstOrDefault(x => x.UserId == user.Id));
        await _userService.DeleteAsync(user, cancellationToken);
        return Ok();
    }

its work but i need to write best code for use the best performance .

How can I improve the efficiency of this code?

1
0
4/15/2019 2:03:53 PM

Accepted Answer

How can I improve the efficiency of this code?

Configure your database to implement cascade deletes on the Foreign Key constraint between User and UserRole, and then from EF you can simply delete the User.

See Cascade Delete - EF Core

And you can delete an entity without first querying it. Just construct an entity instance with the key properties, and attach it to the DbContext in a delted state.

Your controller can be as simple as:

   public async Task<ReturnResult> DeleteUser(DeleteDto deleteDto, CancellationToken cancellationToken)
    {
        using (var db = new Db())
        {
            db.Users.Remove(new User() { Id = deleteDto.id });
            await db.SaveChangesAsync(cancellationToken);
        }
        return Ok();
    }

Without cascade deletes, the only efficient way to do this is with Store Commands. EG:

    public async Task<ReturnResult> DeleteUser(DeleteDto deleteDto, CancellationToken cancellationToken)
    {
        using (var db = new Db())
        using (var tran = db.Database.BeginTransaction())
        {
            await db.Database.ExecuteSqlCommandAsync("delete from UserRole where UserId = @id", cancellationToken, deleteDto.id);
            await db.Database.ExecuteSqlCommandAsync("delete from User where UserId = @id", cancellationToken, deleteDto.id);
            tran.Commit();
        }
        return Ok();
    }
1
4/15/2019 2:26:49 PM

Popular Answer

in onMOdelCreating function, in Entities Class write:

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<User>()
                .HasMany(e => e.UserRole)
                .WithRequired(e => e.User)
                .HasForeignKey(e => e.UserId)
                .WillCascadeOnDelete(true);
        }

in this piece code, deleted all user Roles after deleted a user.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow