【发布时间】:2018-01-28 21:22:24
【问题描述】:
我正在使用实体框架和IUnitOfWork 不重复代码,我的Add 是好的,问题是做Update。
我收到此错误:
附加“ViewModelTicket”类型的实体失败,因为同一类型的另一个实体已经具有相同的主键值。如果图中的任何实体具有冲突的键值,则在使用“附加”方法或将实体的状态设置为“未更改”或“已修改”时,可能会发生这种情况。这可能是因为某些实体是新实体,尚未收到数据库生成的键值。在这种情况下,使用“添加”方法或“已添加”实体状态来跟踪图形,然后将非新实体的状态设置为“未更改”或“已修改”。
我正在使用这个BaseContext 类:
public class BaseContext<T> : DbContext where T : class
{
public DbSet<T> DbSet { get; set; }
public BaseContext() : base("DefaultConnection")
{
//Caso a base de dados não tenha sido criada,
//ao iniciar a aplicação iremos criar
Database.SetInitializer<BaseContext<T>>(null);
}
public virtual void ChangeObjectState(object model, EntityState state)
{
//Aqui trocamos o estado do objeto,
//facilita quando temos alterações e exclusões
((IObjectContextAdapter)this)
.ObjectContext
.ObjectStateManager
.ChangeObjectState(model, state);
}
public virtual int Save(T model)
{
this.DbSet.Add(model);
return this.SaveChanges();
}
public virtual int Update(T model)
{
var entry = this.Entry(model);
if (entry.State == EntityState.Detached)
this.DbSet.Attach(model);
this.ChangeObjectState(model, EntityState.Modified);
return this.SaveChanges();
}
public virtual T GetById(object id)
{
return this.DbSet.Find(id);
}
}
IUnitWork 接口:
public interface IUnitOfWork<T> where T : class
{
int Save(T model);
int Update(T model);
void Delete(T model);
IEnumerable<T> GetAll();
T GetById(object id);
int Max();
IEnumerable<T> Where(Expression<Func<T, bool>> expression);
IEnumerable<T> OrderBy(Expression<System.Func<T, bool>> expression);
}
控制器方法:
public ActionResult SavedTicket(Models.Ticket.ViewModelTicket ticket)
{
if (ModelState.IsValid)
{
if (this.UnitOfTicket.GetById(ticket.TicketId) == null) {
ticket.TicketId = Convert.ToInt32( UnitOfTicket.Max());
ticket.OpenDateAndTime = DateTime.Now;
this.UnitOfTicket.Save(ticket);
} else {
this.UnitOfTicket.Update(ticket);
}
return RedirectToAction(nameof(NewTicket));
}
else {
return View(nameof(NewTicket), ticket);
}
}
谢谢
编辑
我解决了这个问题。
public virtual int Update(T model, int id)
{
var entity = DbSet.Find(id);
this.Entry(entity).CurrentValues.SetValues(model);
return this.SaveChanges();
}
谢谢你们帮助我。
【问题讨论】:
-
您是否还需要在 DbContext 之上的另一个工作单元,它已经是一个工作单元?它有什么用途?看起来您正试图绕过使用视图模型并将实体直接发送到您的视图。更好的解决方案是实际使用视图模型并将它们映射回实体,而不是整个分离/附加场景。
-
我关注了这篇文章netcoders.com.br/…
标签: asp.net-mvc entity-framework