更新通用存储库中的实体时出错

Lor*_*lix 5 c# asp.net-mvc automapper

我正在构建一个通用存储库,除了更新之外,所有其他方法都可以工作.这是代码:

 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();

    }
Run Code Online (Sandbox Code Playgroud)

我正在使用AutoMapper将我的业务模型映射到我的实体模型.在我的控制器中,我有以下内容:

        userModel = userIDService.SelectByID(id);
        userModel.Active = false;
        userIDService.Update(userModel);
Run Code Online (Sandbox Code Playgroud)

该模型运行良好,并将Active值作为False.但它给了我以下错误:

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.
Run Code Online (Sandbox Code Playgroud)

我怎样才能解决这个问题?我尝试过几种方法都没有成功.添加了通用回购代码:

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();
    }
Run Code Online (Sandbox Code Playgroud)

EDIT2:添加了UserIdentification实体

 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; }
}
Run Code Online (Sandbox Code Playgroud)

编辑3:商业模式

    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; }
Run Code Online (Sandbox Code Playgroud)

Nik*_*dze 5

如果DbContext对检索和更新操作使用相同的操作,则在更新时,上下文已跟踪您的实体(具有此主键的实体).来自MSDN:

更改被跟踪实体的状态

您可以通过在其条目上设置State属性来更改已被跟踪的实体的状态.例如:

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(); 
}
Run Code Online (Sandbox Code Playgroud)

请注意,为已跟踪的实体调用"添加"或"附加"也可用于更改实体状态.例如,为当前处于已添加状态的实体调用Attach将将其状态更改为Unchanged.

我想你错过了Attach电话(你注释掉了).请试试

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();
}
Run Code Online (Sandbox Code Playgroud)