Sto costruendo un repository generico e tutti gli altri metodi funzionano con l'eccezione di quello di aggiornamento. Questo è il codice:Errore nell'aggiornamento dell'entità in un repository generico
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();
}
Sto usando AutoMapper per mappare il mio modello di business al mio Entity Model. Nel mio controller ho il seguente:
userModel = userIDService.SelectByID(id);
userModel.Active = false;
userIDService.Update(userModel);
Il modello funziona perfettamente e viene fornito attraverso con il valore attivo come False. Tuttavia mi dà il seguente errore:
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.
Come posso risolvere questo? Ho provato diversi metodi senza successo. Aggiunto generico Codice Repo:
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: Aggiunto 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: Modello di Business
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; }
Si sta utilizzando lo stesso 'DbContext' per recuperare entità e per aggiornare entità? –
Sì, è lo stesso. –
Anche se non sono un fan dei repository generici, posso raccomandare questo post su come costruirne uno: http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5 -utilizzando-mvc-4/attuazione-the-repository-e-di unità di lavoro-patterns-in-un-asp-net-mVC applicazione. –