c# - EF Core 未引发 ValidationException
问题描述
我有一个像这样的基DbContext
类
public abstract class DbContextBase : DbContext
{
public DbContextBase()
{
}
public DbContextBase(DbContextOptions options)
: base(options)
{
}
public override int SaveChanges()
{
this.ValidateEntities();
return base.SaveChanges();
}
public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken))
{
this.ValidateEntities();
return base.SaveChangesAsync(cancellationToken);
}
public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default(CancellationToken))
{
this.ValidateEntities();
return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
}
protected virtual void ValidateEntities()
{
var entities = this.ChangeTracker.Entries().
Where(s => s.State == EntityState.Added || s.State == EntityState.Modified);
foreach (var entity in entities)
{
var validationContext = new ValidationContext(entity);
Validator.ValidateObject(entity, validationContext);
}
}
}
我所有的 Db Context 类都继承自这个基类。问题是即使存在验证违规,该行Validator.ValidateObject()
也不会抛出。ValidationException
在调试器中,我可以看到这一行已执行。例如,对于下面的模型类,我尝试SaveChangesAsync()
使用Name
set to调用,null
但验证通过了:
public class MyModel : IEntity<long>
{
[Key]
public long Id { get; set; }
[Required]
public string Name { get; set; }
}
IEntity<T>
只是将属性强加于Id
所有模型。
解决方案
问题是变量entity
不保存实体实例,而是更改跟踪器(EntityEntry
)实例,所以代码试图验证错误的东西。
所以要么重命名变量并使用entry.Entity
属性:
var entries = this.ChangeTracker.Entries()
.Where(s => s.State == EntityState.Added || s.State == EntityState.Modified);
foreach (var entry in entries)
{
var validationContext = new ValidationContext(entry.Entity);
Validator.ValidateObject(entry.Entity, validationContext);
}
或保持代码不变,但确保entities
变量包含可枚举的实体实例:
var entities = this.ChangeTracker.Entries()
.Where(s => s.State == EntityState.Added || s.State == EntityState.Modified)
.Select(s => s.Entity); // <--
推荐阅读
- arrays - 如何在 C 中替换文本文件中的字符串/短语
- awk - 如何使用 awk 解析 sun solaris 上的测试文件
- firebase - 避免在 Firebase 身份验证迁移中注销用户
- reactjs - Kubernetes 中的后端/前端服务之间没有通信
- linux - 带有条件的基于 Bash 菜单的案例 esac 选择
- r - 从 R 中的 SVD 手动计算伪逆看起来不对?
- flutter - 如何显示附近的用户以便添加他们?
- javascript - 反应 createContext 抛出错误
- android - 无法访问 getSupportFragmentManager()
- c++ - IDA Pro - 将 HIBYTE、LOBYTE 和 __OFSUB__ 宏重写为 C++