5

I have a class Device as follows.

public class Device
{
    public string id { get; set; }
    public string name { get; set; }
    public List<Instructions> Instructions { get; set; }
}

Now I have a view which has sections related to device and provision to add Instrunctions to the device.

If the device is new then this.context.Devices.Add(device) is working fine.

but if I want to edit the device. I find it by Id. It is populated. and if I change the individual property then it is running fine. but I want to update the whole device at once which is not happening.

My sample code is as follows.

public async Task<bool> AddInstrument(Device device)
{
    try
    {
        var newDevice = this.context.Device
                        .Where(i => i.Id == device.Id).FirstOrDefault();//  i tried find,single or default also

        //adding new device
        if (newDevice == null)
        {
            this.context.Device.Add(device);
            return await this.context.SaveChangesAsync() > 0;
        }

        //if editing the device
        newDevice = device;
        return await this.context.SaveChangesAsync() > 0;
    }
    catch
    {
        throw;
    }
} 

what I want to achieve.

problem :- I want to update the corresponding device in the database. along with the instructions. e.g. Previously a device named "D22" has 3 instructions (a1,a2,a3).

but now same device has values name "D22_1" and now instructions are a1,a3(updated any field),a2(deleted). b1 & a4 are added so after editing the fields I have Instructions as a1,a2,b1,b4 for D22_1 .

My effort:-

What I have tried.

1) For main device D22 if I specify properties explicitly it is fine e.g.

device.Name="aaaaa";

this.context.savechanges();

reflects it in database. I have not tried this for updating Instructions in List.

2)I tried to use

this.context.Entry(device).State = EntityState.Modified;

but with various hit and trial I could not run it. The best I could get is this error " This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received .."

Please suggest me something. Moreover I want to know about various techniques related to updating entries with list in EF. I assume EF will automatically take care of the child object (i.e. addition/updation and deletion). In my case Instructions for device.

Learner
  • 1,277
  • 3
  • 15
  • 34
  • [This post](http://stackoverflow.com/questions/13236116/entity-framework-problems-updating-related-objects) shows how to update collection of an entity. Basically, it loops through items in the collection and handles three situations that may occur - item added, item updated, item deleted. – Martin Staufcik Nov 01 '15 at 06:41
  • 1
    newDevice = device; this is the problem: newDevice is in the context, device isn't. since you set the reference to another value, EF can't track it anymore. you'll have to set the attributes one by one or work in a detached scenario. – DevilSuichiro Nov 01 '15 at 08:40
  • @DevilSuichiro how can i do that? work in detached scenario – Learner Nov 01 '15 at 12:52

1 Answers1

0

Try this:

this.context.Attach(device);
this.context.Entry(device).State = EntityState.Modified;
this.context.SaveChangesAsync();
Aleksa
  • 2,976
  • 4
  • 30
  • 49
  • i am getting this error. Attaching an entity of type 'Device' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate. – Learner Nov 02 '15 at 04:39
  • i tried this :-this.context.Device.Attach(newDevice); newDevice= device; this.context.Entry(newDevice).State = System.Data.Entity.EntityState.Modified; – Learner Nov 02 '15 at 04:39