简而言之,在POSTing包装器模型期间抛出异常并将一个条目的状态更改为"已修改".在更改状态之前,状态设置为'Detached'但调用Attach()会产生相同的错误.我正在使用EF6.
请在下面找到我的代码(模型名称已更改,以便于阅读)
模型
// Wrapper classes
public class AViewModel
{
public A a { get; set; }
public List<B> b { get; set; }
public C c { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
调节器
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
if (!canUserAccessA(id.Value))
return new HttpStatusCodeResult(HttpStatusCode.Forbidden);
var aViewModel = new AViewModel();
aViewModel.A = db.As.Find(id);
if (aViewModel.Receipt == null)
{
return HttpNotFound();
}
aViewModel.b = db.Bs.Where(x => x.aID == id.Value).ToList();
aViewModel.Vendor = db.Cs.Where(x => x.cID …Run Code Online (Sandbox Code Playgroud) 错误信息 :
附加"FaridCRMData.Models.Customer"类型的实体失败,因为同一类型的另一个实体已具有相同的主键值.
Attach()如果图中的任何实体具有冲突的>键值,则在使用该方法或将实体的状态设置为"未更改"或"已修改" 时,可能会发生这种情况.这可能是因为某些实体是新的并且尚未收到数据库生成的键值.在这种情况下,使用"添加"方法或"已添加"实体状态来跟踪图形,然后根据需要将非新实体的状态设置为"未更改"或"已修改".
我的代码:
public class FactorController : Controller
{
public JsonResult SaveFactor(Factor factor,int id)
{
if (id > 0)
{
bool result = new FactorService.BaseService.Update(factor);
return new JsonResult() { Data = result };
}
}
}
Run Code Online (Sandbox Code Playgroud)
FactorService.BaseService.cs:
public bool Update(TEntity entity)
{
var entry = context.Entry(entity);
if (entry.State == EntityState.Detached || entry.State == EntityState.Modified)
{
context.Set<TEntity>().Attach(entity);// Error Is Here
entry.State = EntityState.Modified;
context.SaveChanges();
}
return true;
}
Run Code Online (Sandbox Code Playgroud) 错误消息:附加类型的实体失败,因为同一类型的另一个实体已具有相同的主键值.
问题:如何以类似的方式附加实体,如下面的代码中的AttachActivity方法所示?
我必须假设上面的错误消息的"另一个实体"部分是指存在于内存但超出范围(??)的对象.我注意到这一点,因为我尝试附加的实体类型的DBSet的Local属性返回零.
我有理由相信实体在上下文中不存在,因为我逐步完成代码并在创建时观察上下文.在创建dbcontext之后,实体将立即添加到几行中.
我正在测试这里指定的附加实体:找出实体是否附加到dbContext的最合理方法是什么?
当在visual studio的locals窗口中查看本地时,我看到没有类型为Activity的实体(无论ID),除了我想要附加的实体.
代码按以下顺序执行:Try - > ModifyProject - > AttachActivity
代码在注释行的AttachActivity中失败.
请注意调试注释之间的代码,如果已将任何实体添加到上下文中,则将抛出该代码.
private string AttachActivity(Activity activity)
{
string errorMsg = ValidateActivity(activity); // has no code yet. No. It does not query db.
if(String.IsNullOrEmpty(errorMsg))
{
// debug
var state = db.Entry(activity).State; // Detached
int activityCount = db.Activities.Local.Count;
int projectCount = db.Activities.Local.Count;
if (activityCount > 0 || projectCount > 0)
throw new Exception("objects exist in dbcontext");
// end debug
if (activity.ID == 0)
db.Activities.Add(activity);
else
{
db.Activities.Attach(activity); …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Entity Framework 6更新记录,代码优先,没有流畅的映射或像Automapper这样的工具.
entity(Employee)具有与之关联的其他复合属性,如Addreess(collection),Department
它也是从一个名为的基础继承的 User
save方法如下,_dbContext作为DbConext实现
public bool UpdateEmployee(Employee employee)
{
var entity = _dbContext.Employees.Where(c => c.Id == employee.Id).AsQueryable().FirstOrDefault();
if (entity == null)
{
_dbContext.Employees.Add(employee);
}
else
{
_dbContext.Entry(employee).State = EntityState.Modified; // <- Exception raised here
_dbContext.Employees.Attach(employee);
}
return _dbContext.SaveChanges() > 0;
}
Run Code Online (Sandbox Code Playgroud)
我一直收到错误:
附加类型的实体失败,因为相同类型的另一个实体已具有相同的主键值.如果图中的任何实体具有冲突的键值,则在使用"附加"方法或将实体的状态设置为"未更改"或"已修改"时,可能会发生这种情况.这可能是因为某些实体是新的并且尚未收到数据库生成的键值.在这种情况下,使用"添加"方法或"已添加"实体状态来跟踪图形,然后根据需要将非新实体的状态设置为"未更改"或"已修改".
我尝试过以下方法:
EntityState.ModifiedAsNoTracking()查询对象是否存在(没有例外,但DB没有更新) - /sf/answers/1625960101/_dbContext.Users而不是Employee实体进行保存 - /sf/answers/1790294411/现在这些都不适合我.
对于那些不能在我的情况下工作的解决方案,我有什么问题?