C'est la première fois que j'utilise EF dans une application asp.net mvc. Au cours des deux derniers jours, je lis des questions et des exemples semblables, mais jusqu'à maintenant, je n'ai pas compris exactement ce que je devais faire.EF: mise à jour d'une entité avec des entités enfants ajoutées, supprimées ou non (relation plusieurs à plusieurs)
J'ai deux entités avec des relations plusieurs à plusieurs.
Modèle:
[Table("Unit")]
public class UnitEntity
{
[Required]
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public UnitType Type { get; set; }
[StringLength(255)]
public string Title { get; set; }
///some other properties
public virtual ICollection<UserEntity> Users { get; set; }
}
[Table("User")]
public class UserEntity
{
[StringLength(255)]
public string Id { get; set; }
[Required]
public string UserName { get; set; }
[Required]
public string Email { get; set; }
public int Status { get; set; }
// some other properties
public virtual ICollection<UnitEntity> DepartmentUnits { get; set; }
}
Et dans mon dbcontext:
public virtual DbSet<UnitEntity> Units { get; set; }
public virtual DbSet<UserEntity> Users { get; set; }
modelBuilder.Entity<UserEntity>()
.HasMany(e => e.DepartmentUnits)
.WithMany(e => e.Users)
.Map(m => m.ToTable("UserDepartments").MapLeftKey("UserId").MapRightKey("DepartmentId"));
La liste des DepartmentUnits pour chaque utilisateur sont mis à jour dans une vue à l'aide d'une liste Multiselect et transmis au contrôleur.
méthode Contrôleur:
[HttpPost]
public ActionResult UpdateUser(ExternalUserDTO userdata)
{
//list of UnitDepartments from the view
var userDepartments = new List<UnitEntity>();
foreach (var unitid in userdata.DepartmentIds)
{
userDepartments.Add(manager.GetUnit(unitid));
}
//create new user with data to update
UserEntity userentity = new UserEntity()
{
Id = userdata.Id,
DepartmentUnits = userDepartments,
Status = userdata.Status
};
userManager.UpdateUser(userentity);
return new JsonResult { Data = new { Success = false } };
}
Et en classe UserManager:
public void UpdateUser(UserEntity entity)
{
var updentity = this.dataContext.Users.Find(entity.Id);
if (updentity == null)
throw new NullReferenceException("User not found");
updentity.Status = entity.Status;
var newUnitIds = entity.DepartmentUnits.Select(u => u.Id);
var existingUnitIds = updentity.DepartmentUnits.Select(u => u.Id);
updentity.DepartmentUnits.Where(u => !newUnitIds.Contains(u.Id)).ToList().ForEach(d => updentity.DepartmentUnits.Remove(d));
entity.DepartmentUnits.Where(u => newUnitIds.Except(existingUnitIds).Contains(u.Id)).ToList().ForEach(d => updentity.DepartmentUnits.Add(d));
this.dataContext.Entry(updentity).State = EntityState.Modified;
foreach (var deptentity in updentity.DepartmentUnits)
{
if(newUnitIds.Contains(deptentity.Id))
{
this.dataContext.Entry(deptentity).State = EntityState.Added;
}
if(existingUnitIds.Contains(deptentity.Id))
{
this.dataContext.Entry(deptentity).State = EntityState.Unchanged;
}
}
try
{
this.dataContext.SaveChanges();
}
catch (Exception)
{
throw new Exception("Update problem");
}
}
Je dois mettre à jour ma table UserDepartments (voir constructeur de modèle ci-dessus), afin de supprimer enlevé, ajouter de nouvelles et de conserver DepartmentUnits existants pour l'utilisateur spécifique. Ce qui précède ne fonctionne pas, je suis perdu et j'apprécie toute aide.
FWIW, cette ligne: '.CurrentValues.SetValues this.dataContext.Entry (dbEntity) (entité),' émet une exception sur les entités étant dans un contexte différent. Cette ligne: 'dbEntity.DepartmentUnits = entity.DepartmentUnits.Select (e => new UnitEntity {Id = e.Id}). ToList();' ajoute une nouvelle ligne dans la table Unit avec des valeurs nulles et ajoute une entrée à la table UserDepartments avec un UnitId qui n'existe pas réellement. Néanmoins, vous avez résolu mon problème parce que vous m'avez fait réfléchir d'une autre manière. Merci beaucoup, je vais mettre ma solution de travail ci-dessous. – tz2015