I have a room including some users. I want to remove an specific user from the room.
Here are my Models:
public class RoomModel
{
[Required]
public int Id { get; set; }
public string Name { get; set; }
public string Admin { get; set; }
public ICollection<UserModel> Users { get; set; }
}
public class UserModel
{
[Key]
public string UserID { get; set; }
public string UserName { get; set; }
}
And my database context:
public class DBContext : IdentityDbContext
{
public DBContext()
{
}
public DBContext(DbContextOptions<DBContext> options) : base(options)
{
}
public DbSet<RoomModel> Rooms { get; set; }
public DbSet<UserModel> Users { get; set; }
}
How can I remove an specific user from the room and save changes in database?
CodePudding user response:
Load rooms with navigation property Users, then find the user to remove.
var userId = "1234-ABC";
// Eager loading
var rooms = db.Rooms
.Include(u => u.Users)
.ToList();
// or Explicit loading
// var rooms = db.Rooms.Collection(u => u.Users).Load();
var user = rooms.Users.Where(u => u.UserId == userId).FirstOrDefault();
rooms.Users.Remove(user); // should check if user is not null
// now you can save changes to db
db.SaveChanges();
CodePudding user response:
Since in your UserModel
enity there is no CLR property which holds the foreign key for the relationship, a shadow property RoomModelId
is created.
See the documentation for more information: Shadow and Indexer Properties.
We can use this shadow property to efficiently perform the deletion without making unnecessary queries to the database.
// We get the room somehow.
var room = db.Rooms.First(r => r.Name == "room A");
// Create a user with the desired id.
var user = new UserModel { UserID = "x" };
// Or we get a user from the database. But this is an unnecessary query.
//var user = db.Users.First(u => u.UserID == "x");
// Set the foreign key value to the shadow property.
db.Entry(user).Property("RoomModelId").CurrentValue = room.Id;
// Mark entity as deleted.
db.Entry(user).State = EntityState.Deleted;
db.SaveChanges();
I would add the following properties to the UserModel
, for more convenience:
public int RoomModelId { get; set; }
public RoomModel Room { get; set; }