Uso Entity Framework 6 in un progetto MVC 5 e vi è una relazione di entità tra Experiment e FileAttachment (un Experiment può fornire molti FileAttachment). Durante la modifica di un record di esperimento, carico un ViewModel contenente entrambe le entità e elenco gli allegati sotto l'esperimento in modalità di modifica:
Lo scenario è come spiegato di seguito:
1) C'è un pulsante Elimina per ogni FileAttachment e quando l'utente cancella un allegato, viene eliminato tramite AJAX e visualizza un messaggio informativo sulla stessa finestra modale.
2) Tuttavia, se l'utente aggiunge un nuovo allegato dopo aver eliminato un allegato e salvato l'Esperimento, si verifica il seguente errore:
"L'istruzione di aggiornamento, inserimento o cancellazione del negozio ha interessato un numero imprevisto di righe (0). Le entità potrebbero essere state modificate o eliminate dal momento in cui le entità sono state caricate."
context.Entry(f).State = EntityState.Added,
context.Entry(f).State = EntityState.Modified
e context.Entry(f).State = EntityState.Unchanged
non ha alcun senso. Cosa devo fare per collegare semplicemente il FileAttachment appena aggiunto al database ? Modelli:
public class Experiment
{
[Key]
public int Id { get; set; }
public int Number { get; set; }
public string Name { get; set; }
//Navigation Properties
public virtual ICollection<FileAttachment> FileAttachments { get; set; }
}
public class FileAttachment
{
[Key]
public int Id { get; set; }
public int ExperimentId { get; set; }
public string FileName { get; set; }
public byte[] FileData { get; set; }
[HiddenInput(DisplayValue = false)]
public string FileMimeType { get; set; }
//Navigation Properties
public virtual Experiment Experiment { get; set; }
}
ViewModel:
public class ExperimentViewModel
{
//code omitted for brevity
[DataType(DataType.Upload)]
public IEnumerable<HttpPostedFileBase> FileUpload { get; set; }
public virtual ICollection<FileAttachment> FileAttachments { get; set; }
}
controller:
public JsonResult Update([Bind(Exclude = null)] ExperimentViewModel model)
{
List<FileAttachment> fa = new List<FileAttachment>();
//code omitted for brevity (At this step I add all the attachments in the model to "fa" paarmeter)
//Mapping ViewModel to Entity Model (ExperimentViewModel > Experiment) :::::::::::::::::
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<ExperimentViewModel, Experiment>();
});
IMapper mapper = config.CreateMapper();
//var source = new ExperimentViewModel();
var dest = mapper.Map<ExperimentViewModel, Experiment>(model);
////::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
repository.SaveExperimentWithAttachment(dest, fa);
}
Calcestruzzo:
public void SaveExperimentWithAttachment(Experiment experiment, IEnumerable<FileAttachment> fileAttachment)
{
//Update Block
using (var context = new EFDbContext())
{
context.Entry(experiment).State = EntityState.Modified;
foreach (FileAttachment f in fileAttachment)
{
context.Entry(f).State = EntityState.Modified;
}
context.SaveChanges();
}
}
Ecco la risposta finale risolvendo i problemi con l'aiuto di @StephenMuecke e @ haim770 . Mille grazie per l'impegno e il gentile aiuto ... Cordiali saluti.
public void SaveExperimentWithAttachment(Experiment experiment, IEnumerable<FileAttachment> fileAttachment)
{
using (var context = new EFDbContext())
{
context.Entry(experiment).State = EntityState.Modified;
foreach (FileAttachment f in fileAttachment)
{
// !!! I forgot to update the ExperimentId field for each file attachment
f.ExperimentId = experiment.Id;
context.Entry(f).State = EntityState.Added; //Because file attachment(s) is not updated, newly ADDED
}
context.SaveChanges();
}
}