使用IUnitOfWork更新实体框架

时间:2018-01-27 15:03:08

标签: asp.net-mvc entity-framework

我正在使用实体框架而IUnitOfWork不重复代码,我的Add没问题,问题是Update

我收到此错误:

  

附加类型' ViewModelTicket'的实体失败,因为同一类型的另一个实体已具有相同的主键值。使用'附加'方法或将实体的状态设置为“未更改”#39;或者'修改'如果图中的任何实体具有冲突的键值。这可能是因为某些实体是新的并且尚未收到数据库生成的键值。在这种情况下,请使用'添加'方法或“添加”#39;实体状态跟踪图形,然后将非新实体的状态设置为“未更改”。或者'修改'酌情。

我正在使用此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();
 }

谢谢你们帮助我。

1 个答案:

答案 0 :(得分:0)

在插入新实体时,您是否不能生成下一个更高的ID?

class Comment < ApplicationRecord
attr_accessor :content
belongs_to :wad
belongs_to :user
end