Amir Imam
Amir Imam

Reputation: 1043

EF 6 Insert,Update and delete with generic method

I created web service asp API width EF 6 to connect sql server .. and I created generic method to execute Insert & Update & Delete .. the method is

    protected enum ExecuteActions
    {
        Insert,
        Update,
        Delete
    }
protected ResponseResult Execute<T>(T entity,ExecuteActions exAction) where T:class
{
      var model = db.Set<T>();
      switch (exAction)
                {
                    case ExecuteActions.Insert:
                        model.Add(entity);
                        break;
                    case ExecuteActions.Update:
                        model.Attach(entity);
                        db.Entry(entity).State = System.Data.Entity.EntityState.Modified;
                        break;
                    case ExecuteActions.Delete:
                        model.Attach(entity);
                        db.Entry(entity).State = System.Data.Entity.EntityState.Deleted;
                        break;

                    default:
                        break;
                }
                  db.SaveChanges();    
}

The Insert is working fine, but the problem is in the Update case .. the incomprehensible thing that is working with some entities and some others throws error

Attaching an entity of type 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' 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.

I found some solutions that explains that I have to use (Find) to get the entity than update it .. but its not compatible with my work .. because I don't know the ID of the generic type in the method.

and I tried this too

In another project it works by something like this method .. so I thought the problem with entity framework element (edmx) .. so I deleted it and recreated it but nothing happened

Upvotes: 1

Views: 1456

Answers (1)

MORCHARD
MORCHARD

Reputation: 263

Create an interface for your entity types such as:

public interface IKeyed{
     int KeyValue{get;}
}

Then have your entities implement the interface such as:

public partial class Foo : IKeyed{
     public int KeyValue {get {return this.Id;}}
     public int Id {get; set;}
}

And then update your Generic method signature to define T as IKeyed

protected ResponseResult Execute<T>(T entity,ExecuteActions exAction) 
                                    where T : class, IKeyed

And then reference

entity.KeyValue 

when using the Entity Framework's "Find" method.

Upvotes: 3

Related Questions