该代码在Entity Framework 1.0中运行良好也可以是1.1。
var pupilFound = await context.Pupils.SingleOrDefaultAsync(p => p.Id == pupil.Id);
if (pupilFound == null)
{
throw new BadDataException($"{nameof(pupil.Id)} is not valid");
}
if (pupilFound.UserId != userId)
{
throw new NotAuthorizedException();
}
pupil.UserId = userId;
context.Entry(pupil).State = EntityState.Modified;
await contextSaveChangesAsync();
现在有了Entity Framework Core 2.0,我得到了一个错误:
Cannot be tracked because another instance of this type with the same key is already being tracked
快速解决方法是:
var pupilFound = await context.Pupils.AsNoTracking.SingleOrDefaultAsync(p => p.Id == pupil.Id);
这种方式跟踪被禁用,但这违背了关于官方推荐的AsNoTracking方法的目的:
Disabling change tracking is useful for read-only scenarios because it avoids
// the overhead of setting up change tracking for each entity instance. You should
// not disable change tracking if you want to manipulate entity instances and persist
// those changes to the database using Microsoft.EntityFrameworkCore.DbContext.SaveChanges
如何更新学生的所有属性来自客户?
答案 0 :(得分:0)
正如评论中所说的那样,这个代码在以前的测试中运行的可能性非常小。" beta" EF-core的版本(即< v.2)。他们是马车,但那坏。
无论如何,你在那里做了很多可能不那么礼仪的事。
首先,应该通过应用filters在处理管道中更早地处理与授权相关的任何事情,因此您不必一次又一次地编写此重复代码。但这是一个偏离主题的地方。 (假设你在ASP.Net工作)。
其次,在主题上,你真的不需要检查数据库中是否存在id。只需将pupil
对象附加为已修改并保存更改即可。无论如何你必须捕获异常,所以为什么不专门捕捉DbUpdateException
,当同时删除学生时(以及其他可能的原因),这将被抛出。