0

Quick background: I am trying to write an Edit HttpPost Action.

public async Task<ActionResult> Edit (myViewModel model){ 
    if(ModelState.IsValid){
        myObject x = await db.myObjects.FindAsync(model.Id);
        db.Entry(x).State = EntityState.Modified;

        // code to map model to x

        await db.SaveChangesAsync();

        //...

The SaveChangesAsync() line gives an error: "Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.


Now the weird part: When I add lines such as

 Console.Write(x.property1);
 Console.Write(x.property2.name);

etc. for all the properties of x, then do the mapping from model to x and then savechanges, the error does not occur and the code behaves as I expect it to.

Please help, thank you.


EDIT: EntityValidationErrors say x.prop1 and x.prop2 are required. Another fix I discovered: writing x.prop1 = x.prop1; before db.SaveChangesAsync(); Feels weird but it is working.


EDIT 2: My code in detail:

public class myObject{
    public int Id {get; set;}

    [Required]
    public virtual y prop1 {get; set;}

    [Required]
    public virtual z prop2 {get; set;}

    [Required]
    public string prop3 {get; set;}

    [Required]
    public string prop4 {get; set;}
}

And here is the mapping code:

if(ModeState.IsValid){
    myObject x = await db.myObjects.FindAsync(model.Id);
    db.Entry(x).State = EntityState.Modified;

    x.prop3 = model.editedValueForProp3;

    db.myObjects.AddOrUpdate(x);
    await db.SaveChangesAsync(); 
    return RedirectToAction("Index");
}

Things to note: I only get validation errors for prop1 and prop2 which are virtual properties. The errors disappear if I write these lines before db.SaveChangesAsync()

x.prop1 = x.prop1;
x.prop2 = x.prop2;

I am using lazy loading. Could that be the problem?

Sohaib Afzal
  • 105
  • 1
  • 9
  • 1
    What was `EntityValidationErrors` returned? And where you placed 2 `Console.Write` lines before validation error disappear? – Tetsuya Yamamoto Apr 21 '17 at 08:07
  • See if this is helpful https://stackoverflow.com/questions/29231445/a-first-chance-exception-of-type-system-data-entity-validation-dbentityvalidati/29231832#29231832 – Mukesh Modhvadiya Apr 21 '17 at 09:48
  • @TetsuyaYamamoto Thank you for your comments. EntityValidationErrors say that some properties of x are required. However, when I Debug.WriteLine(x.prop1.Id) it shows the correct value. Why does it think x.prop1 doesn't have a value when saving changes? Console.Write lines were placed just before code to map the model to x. – Sohaib Afzal Apr 25 '17 at 09:29
  • @MukeshModhvadiya Thank you for your comment. The errors say x.prop1 and x.prop2 are required. However, when I check the values of x.prop1.id and x.prop2.id using Debug.WriteLine, it shows that correct values exist in x. – Sohaib Afzal Apr 25 '17 at 09:31
  • @SohaibAfzal, can you please show your entity class and code to map model to x? – Mukesh Modhvadiya Apr 25 '17 at 09:56
  • @MukeshModhvadiya I am editing my main post with code. – Sohaib Afzal Apr 25 '17 at 14:11
  • After changing entity state to modified, you don't need to call AddOrUpdate(). Remove it! – Mukesh Modhvadiya Apr 25 '17 at 15:15
  • @MukeshModhvadiya I have tried and if I remove AddOrUpdate, the database does not get updated with the edit. The automatically scaffolded code made by Visual Studio for Edit actions also contains both EntityState.Modified and AddOrUpdate, so I don't think that is the issue. – Sohaib Afzal Apr 26 '17 at 07:08
  • @SohaibAfzal, are you sure? – Mukesh Modhvadiya Apr 26 '17 at 10:06
  • @MukeshModhvadiya Yes. I tried it before replying. – Sohaib Afzal Apr 26 '17 at 10:29
  • I request you also remove entity state modified line in addtion to AddOrUpdate, just get it from db, update the fields and db.SaveChanges(), can you try? – Mukesh Modhvadiya Apr 26 '17 at 10:36
  • 1
    @MukeshModhvadiya Sorry I misunderstood last time, AddOrUpdate can be removed. If then I don't do x.prop1 = x.prop1 etc then I get the entityValidationError. If I do x.prop1 = x.prop1 etc then the changes are saved. So you are right, that line can be omitted. I tried removing both the Modified and the AddOrUpdate line, leaving just the SaveChanges line, but the error persists if I don't write x.prop1 = x.prop1 etc. – Sohaib Afzal Apr 27 '17 at 06:35

1 Answers1

0

As I understand, the problem was due to lazy loading. I have changed the call to the database as follows:

myObject x = await db.myObjects
.Include(a => a.prop1)
.Include(a => a.prop2)
.FirstOrDefaultAsync(a => a.Id == model.Id);

That has solved my problem. Thanks to all who helped. :)

Sohaib Afzal
  • 105
  • 1
  • 9