I am building a Generic Repository and all other methods work with the exception of the update one. This is the code:
public void Update(T1 obj)
{
T2 item = Mapper.Map<T1, T2>(obj);
//db.Entry(item).State = EntityState.Modified;
//db.Set<T2>().Attach(item);
db.Entry<T2>(item).State = EntityState.Modified;
db.SaveChanges();
}
I am using AutoMapper to map my business model to my Entity Model. In my controller I have the following:
userModel = userIDService.SelectByID(id);
userModel.Active = false;
userIDService.Update(userModel);
The model works perfectly and it comes through with the Active value as False. Yet it gives me the following error:
Attaching an entity of type 'Data.UserIdentification' 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.
How can I fix this? I've tried several methods to no success. Added Generic Repo Code:
public class GenericRepository<T1, T2>:IGenericRepository<T1>
where T1 : class
where T2: class
{
private Data.Entities db = null;
private DbSet<T2> table = null;
public GenericRepository()
{
this.db = new Data.Entities();
table = db.Set<T2>();
}
public GenericRepository(Entities db)
{
this.db = db;
table = db.Set<T2>();
}
public IQueryable<T1> SelectAll()
{
return table.ToList().AsQueryable().Select(x => Mapper.Map<T2, T1>(x));
}
public T1 SelectByID(object id)
{
return Mapper.Map<T2, T1>(table.Find(id));
}
public void Insert(T1 obj)
{
T2 item = Mapper.Map<T1, T2>(obj);
table.Add(item);
}
public void Update(T1 obj)
{
//T2 item = Mapper.Map<T1, T2>(obj);
//table.Attach(item);
//db.Entry<T2>(item).State = EntityState.Modified;
//db.SaveChanges();
T2 item = Mapper.Map<T1, T2>(obj);
db.Set<T2>().Attach(item);
db.Entry<T2>(item).State = EntityState.Modified;
db.SaveChanges();
}
public void Delete(object id)
{
T2 existing = table.Find(id);
table.Remove(existing);
}
public void Save()
{
db.SaveChanges();
}
EDIT2: Added UserIdentification Entity
public partial class UserIdentification
{
public System.Guid id { get; set; }
public System.Guid user_id { get; set; }
public int id_type { get; set; }
public System.DateTime expiration_date { get; set; }
public System.DateTime Created { get; set; }
public Nullable<bool> Active { get; set; }
public virtual IdentificationType IdentificationType { get; set; }
public virtual UserInfo UserInfo { get; set; }
}
EDIT 3: Business Model
public Guid id { get; set; }
public System.Guid user_id { get; set; }
public int id_type { get; set; }
public System.DateTime expiration_date { get; set; }
public System.DateTime Created { get; set; }
public Nullable<bool> Active { get; set; }
public virtual IdentificationType IdentificationType { get; set; }
If you use the same DbContext
for both retrieve and update operations, then your context already tracks your entity (entity with this primary key) when you update. From MSDN:
Changing the state of a tracked entity
You can change the state of an entity that is already being tracked by setting the State property on its entry. For example:
var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };
using (var context = new BloggingContext())
{
context.Blogs.Attach(existingBlog);
context.Entry(existingBlog).State = EntityState.Unchanged;
// Do some more work...
context.SaveChanges();
}
Note that calling Add or Attach for an entity that is already tracked can also be used to change the entity state. For example, calling Attach for an entity that is currently in the Added state will change its state to Unchanged.
I think you are missing the Attach
call (that you commented out). Please try
public void Update(T1 obj)
{
T2 item = Mapper.Map<T1, T2>(obj);
db.Set<T2>().Attach(item);
db.Entry<T2>(item).State = EntityState.Modified;
db.SaveChanges();
}
I'm just going to leave this here:
https://vimeo.com/131633177
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With