到目前为止,我一直为现有值、最小值、最大值、长度等验证我的 dto 属性。
现在,我的 http api 有一个用例,其中 http 帖子的有效负载包含数据库中不存在的 ID(数据库外键),或者这些 ID 不属于不记名令牌内的 userId。UserId 始终是每个表中的一个字段。
我真的应该写一个存储库方法吗:
// done with 3 queries still room for optimization...
public bool NewTestTypeIsValid(string userId,int schoolyearId, int schoolclassId, int subjectId)
{
return context.TestTypes.SingleOrDefault(x => x.userId == userId && x.schoolyearId == schoolyearId) != null &&
context.Schoolclasses.SingleOrDefault(x => x.userId == userId && x.schoolclassId == schoolclassId) != null &&
context.Subjects.SingleOrDefault(x =>x.userId == userId && x.subjectId == subjectId) != null;
}
检查测试类型的 http 帖子是否有效/无效,如果无效则返回 400 错误数据?
为了让这个问题更难回答,我提供了一个更真实的示例:
当这些数据通过 http 发布到服务器时,我不仅需要验证 subjectId、schoolclassId、schoolyearId,还需要验证每个TestTypeId
更新的TestType
数据不是来自 REST 端点,我只需要它的肥皂风格:-)
public async Task<IEnumerable<TestType>> SaveTestTypesAsync(List<TestType> testTypes, int schoolyearId, int schoolclassId, int subjectId, string userId)
{
var testTypesFromDatabase = await context.TestTypes
.Include(t => t.Subject)
.Include(s => s.Schoolclass)
.Where(p =>
p.Schoolclass.Id == schoolclassId &&
p.Subject.Id == subjectId && p.UserId == userId
)
.AsNoTracking()
.ToListAsync();
var schoolclass = new Schoolclass { Id = schoolclassId };
var subject = new Subject { Id = subjectId };
var schoolyear = new Schoolyear { Id = schoolyearId };
// Make the navigation properties available during SaveChanges()
context.Attach(schoolclass);
context.Attach(subject);
context.Attach(schoolyear);
// DELETE
var testTypesToRemove = testTypesFromDatabase.Except(testTypes, new TestTypeComparer()).ToList();
context.TestTypes.RemoveRange(testTypesToRemove);
// ADD
var testTypesToAdd = testTypes.Where(t => t.Id == 0).ToList(); //
foreach (var testType in testTypesToAdd)
{
testType.Schoolclass = schoolclass;
testType.Subject = subject;
testType.Schoolyear = schoolyear;
}
context.TestTypes.AddRange(testTypesToAdd);
// UPDATE
var modifiedTestTypesToUpdate = testTypes.Except(testTypesToAdd.Concat(testTypesToRemove).ToList(), new TestTypeComparer()).ToList();
foreach (var testType in modifiedTestTypesToUpdate)
{
testType.Schoolclass = schoolclass;
testType.Subject = subject;
testType.Schoolyear = schoolyear;
}
context.UpdateRange(modifiedTestTypesToUpdate);
await context.SaveChangesAsync();
return await this.GetTestTypesConfigurationAsync(schoolclassId, subjectId, userId);
}