gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 22:36:44 24 4
gpt4 key购买 nike

我正在构建一个通用存储库,所有其他方法都可以使用,但更新方法除外。这是代码:

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

}

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

        userModel = userIDService.SelectByID(id);
userModel.Active = false;
userIDService.Update(userModel);

该模型运行良好,并且 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.

我该如何解决这个问题?我尝试了几种方法都没有成功。添加了通用 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:添加了 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; }
}

编辑 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; }

最佳答案

如果您对检索和更新操作使用相同的 DbContext,那么在您更新时,您的上下文已经跟踪了您的实体(具有此主键的实体)。来自 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.

我认为您缺少 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();
}

关于c# - 更新通用存储库中的实体时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31685516/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com