How to avoid optimistic concurrency error for newly added record in EF

asp.net asp.net-mvc entity-framework entity-framework-6 optimistic-concurrency

Question

In an MVC 5 project I'm working on, I'm using Entity Framework 6, and Experiment and FileAttachment have entity relations (one Experiment can gave many FileAttachment). I load a ViewModel containing both entities while editing an experiment record, and the experiment's attachments are included there as well:

The situation is described below:

1) Each FileAttachment has a Delete button, and when a user clicks that button, an attachment is removed using AJAX and an informational message is shown in the same modal window.

2) However, the following problem is seen if the user adds a new attachment after removing an attachment and saves the experiment:

"Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded."

  • The cause, in my opinion, is that I loaded the FileAttachment and Experiment entities before changing the FileAttachment entity by removing a record. However, the identical entity that was loaded the first time is still there, and I want to preserve it. So maybe before saving, I need to establish an entity and fill it out, butcontext.Entry(f).State = EntityState.Added,context.Entry(f).State = EntityState.Modified and context.Entry(f).State = EntityState.Unchanged doesn't make sense at all. What ought I to do with just add the most recent FileAttachment to the database.?

Models:

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);
}

Concrete:

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


1
2
10/10/2016 12:10:55 PM

Popular Answer

ZZZ_tmp
0
10/10/2016 12:00:04 PM


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