添加多行受影响但未更新(C#,Entity Framework 6)
Adding Mutliple Row Effected properly but not Updating (C#, Entity Framework 6)
如下所示,我正在尝试更新 "active" 和 "version" 字段,它们是 templateData 对象的属性。
当我想添加一条新记录时,它运行良好,满足需求。但是当我尝试更新 state.modified 行时,错误是:
Attaching an entity of type '...' failed because another entity 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 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.
尽管我尝试了很多崩溃的方法(如您所见),但我没有成功。
这个错误的原因是什么?我该如何处理?
感谢您的帮助。
服务:
public ResultObject<TemplateData> SaveTemplateData(TemplateData oTemplateData)
{
var oResult = new ResultObject<TemplateData>();
using (var contextTransaction = _context.Database.BeginTransaction())
{
try
{
var listTempDatas = _context.TemplateDatas.Where(td => td.TemplateRID == oTemplateData.TemplateRID)
.ToList();
#region active/version
oTemplateData.Active = true;
if (listTempDatas.Count > 0)
{
#region resetActives
listTempDatas.ForEach(ltd => ltd.Active = false);
#endregion
#region getMaxVersion
var maxVersionValue = listTempDatas.Max(ltd => ltd.TemplateVersion);
//var maxVersionValue2 = listTempDatas.OrderByDescending(ltd => ltd.TemplateVersion).Select(ltd => ltd.TemplateVersion).First();
oTemplateData.TemplateVersion = maxVersionValue + 1;
#endregion
}
else if (listTempDatas.Count == 0)
{
oTemplateData.TemplateVersion = 1;
}
#endregion
if (oTemplateData.ID > 0)
{
var oldTempData = _context.TemplateDatas.AsNoTracking()
.FirstOrDefault(td => td.ID == oTemplateData.ID);
if (oldTempData != null)
_context.Entry(oTemplateData).State = EntityState.Modified;// and there it is
}
else if (oTemplateData.ID == 0)
{
_context.Entry(oTemplateData).State = EntityState.Added;
}
_context.SaveChanges();
oResult.ResulObject = oTemplateData;
contextTransaction.Commit();
}
catch (Exception e)
{
contextTransaction.Rollback();
oResult.AddError("TemplateService.SaveTemplateData", e.ToString());
}
}
return oResult;
}
实体:
public class TemplateData
{
...
public int ID { get; set; }
public int? TemplateRID { get; set; }
...
public int? TemplateVersion { get; set; }
public bool? Active { get; set; }
...
public virtual Template Template { get; set; }
}
DataContextExtension:
public static ApplicationDbContext BulkInsert<T>(this ApplicationDbContext context, T entity, int count,
int batchSize) where T : class
{
context.Set<T>().Add(entity);
if (count % batchSize == 0)
{
context.SaveChanges();
context.Dispose();
context = new ApplicationDbContext();
// This is optional
context.Configuration.AutoDetectChangesEnabled = false;
}
return context;
}
问题是那行
var listTempDatas = _context.TemplateDatas.Where(td => td.TemplateRID == oTemplateData.TemplateRID)
.ToList();
已经在上下文中加载(跟踪)您正在尝试更新的现有实体。
所以首先您可以尝试在该列表中找到它(而不是使用单独的数据库查询):
var oldTempData = listTempDatas.FirstOrDefault(td => td.ID == oTemplateData.ID);
然后简单地更新现有实体的属性,而不是尝试将分离的实体标记为已修改:
if (oldTempData != null)
_context.Entry(oldTempData).CurrentValues.SetValues(oTemplateData); // and there you go
如下所示,我正在尝试更新 "active" 和 "version" 字段,它们是 templateData 对象的属性。
当我想添加一条新记录时,它运行良好,满足需求。但是当我尝试更新 state.modified 行时,错误是:
Attaching an entity of type '...' failed because another entity 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 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.
尽管我尝试了很多崩溃的方法(如您所见),但我没有成功。
这个错误的原因是什么?我该如何处理?
感谢您的帮助。
服务:
public ResultObject<TemplateData> SaveTemplateData(TemplateData oTemplateData)
{
var oResult = new ResultObject<TemplateData>();
using (var contextTransaction = _context.Database.BeginTransaction())
{
try
{
var listTempDatas = _context.TemplateDatas.Where(td => td.TemplateRID == oTemplateData.TemplateRID)
.ToList();
#region active/version
oTemplateData.Active = true;
if (listTempDatas.Count > 0)
{
#region resetActives
listTempDatas.ForEach(ltd => ltd.Active = false);
#endregion
#region getMaxVersion
var maxVersionValue = listTempDatas.Max(ltd => ltd.TemplateVersion);
//var maxVersionValue2 = listTempDatas.OrderByDescending(ltd => ltd.TemplateVersion).Select(ltd => ltd.TemplateVersion).First();
oTemplateData.TemplateVersion = maxVersionValue + 1;
#endregion
}
else if (listTempDatas.Count == 0)
{
oTemplateData.TemplateVersion = 1;
}
#endregion
if (oTemplateData.ID > 0)
{
var oldTempData = _context.TemplateDatas.AsNoTracking()
.FirstOrDefault(td => td.ID == oTemplateData.ID);
if (oldTempData != null)
_context.Entry(oTemplateData).State = EntityState.Modified;// and there it is
}
else if (oTemplateData.ID == 0)
{
_context.Entry(oTemplateData).State = EntityState.Added;
}
_context.SaveChanges();
oResult.ResulObject = oTemplateData;
contextTransaction.Commit();
}
catch (Exception e)
{
contextTransaction.Rollback();
oResult.AddError("TemplateService.SaveTemplateData", e.ToString());
}
}
return oResult;
}
实体:
public class TemplateData
{
...
public int ID { get; set; }
public int? TemplateRID { get; set; }
...
public int? TemplateVersion { get; set; }
public bool? Active { get; set; }
...
public virtual Template Template { get; set; }
}
DataContextExtension:
public static ApplicationDbContext BulkInsert<T>(this ApplicationDbContext context, T entity, int count,
int batchSize) where T : class
{
context.Set<T>().Add(entity);
if (count % batchSize == 0)
{
context.SaveChanges();
context.Dispose();
context = new ApplicationDbContext();
// This is optional
context.Configuration.AutoDetectChangesEnabled = false;
}
return context;
}
问题是那行
var listTempDatas = _context.TemplateDatas.Where(td => td.TemplateRID == oTemplateData.TemplateRID)
.ToList();
已经在上下文中加载(跟踪)您正在尝试更新的现有实体。
所以首先您可以尝试在该列表中找到它(而不是使用单独的数据库查询):
var oldTempData = listTempDatas.FirstOrDefault(td => td.ID == oTemplateData.ID);
然后简单地更新现有实体的属性,而不是尝试将分离的实体标记为已修改:
if (oldTempData != null)
_context.Entry(oldTempData).CurrentValues.SetValues(oTemplateData); // and there you go