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?
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.
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();
}
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.