在网络服务中,我有一个包含“Seq”字段的表:它是一个计数器,为了我的应用程序,它必须填充一系列整数值,没有间隙。该序列可能会被“破坏”(例如,如果记录被删除或其他情况)。 然后,我有一种类似于下面的方法,可以对“Seq”字段重新编号。 我已经测试过它(也在许多其他表中)并且它工作得很好。
[HttpPut("RenumberSeq")]
public async Task<IActionResult> RenumberSeq()
{
var orderedEntities =
await _context._UT_Risorse
.OrderBy(r => r.Seq)
.ToListAsync();
var newSeq = 1;
foreach (var obj in orderedEntities)
{
obj.Seq = newSeq;
newSeq++;
}
await _context.SaveChangesAsync();
return NoContent();
}
问题是这个表(与我使用相同方法的其他表不同)有一个名为“base64”的字段,其中包含非常长的字符串:它实际上是一个用于存储base64格式文件的字段。
由于这个字段如此繁重,该方法可以工作,但速度非常慢:甚至需要 30 秒才能对 15 条记录进行重新编号,每条记录包含 30 到 50 kb 的字符串... 然后我认为重新编写查询可能是个好主意:
var orderedEntities =
await (from r in _context._UT_Risorse
select new _UT_Risorsa
{
ID = r.ID,
NomeFile = r.NomeFile, //this is a non relevant field
TipoFile = r.TipoFile, //this is a non relevant field
Seq = r.Seq, //this is the field to renumber
})
.OrderBy(r => r.Seq)
.ToListAsync();
await _context.SaveChangesAsync();
return NoContent();
所以包括我需要的所有字段,但跳过“base64”重字段。 问题是,如果我这样写,await _context.SaveChangesAsync() 不起作用。我没有收到错误,但数据库表没有显示任何变化。
这就好像 SaveChangesAsync 需要处理整个记录而无法处理部分记录......这是该方法的正确行为吗?我可以做些什么来保留我的部分查询(因此避免包含“base64”字段以保持快速)并进行保存?
正如埃尔达尔建议的那样,我今天早上发现事实确实如他所说。 EF 的假定行为是编辑并保存整个记录。 这就是我设法解决的方法
var orderedEntities =
await (from r in _context._UT_Risorse
select new _UT_Risorsa
{
ID = r.ID,
Seq = r.Seq,
})
.OrderBy(r => r.Seq)
.ToListAsync();
var newSeq = 1;
foreach (var obj in orderedEntities)
{
//procedure to edit only part of the record
var entityToUpdate = new _UT_Risorsa { ID = obj.ID, Seq = newSeq };
_context.Attach(entityToUpdate);
_context.Entry(entityToUpdate).Property(r => r.Seq).IsModified = true;
newSeq++;
}
await _context.SaveChangesAsync();
return NoContent();
现在它很完美:非常快速且有效。 这是我得到答案的链接 https://kontext.tech/article/638/entityframework-core-update-only-one-field