如何防止EF在DBContext.SaveChanges()期间验证未映射的属性

本文关键字:验证 映射 属性 EF 何防止 DBContext SaveChanges | 更新日期: 2023-09-27 18:05:23

我有一个用户模型,有两个[NotMapped]字符串属性Password和ConfirmPassword。这些是未映射的,因为我将密码保存为字节数组(盐化后),所以在用户模型中有两个额外的属性(映射)InternalPassword和Salt。

问题是当我使用用户模型更改密码时,实体框架抛出DBEntityValidation错误,指出"需要密码属性"。我在这里理解的是,EF在保存之前试图验证我的模型,并且由于密码/ConfirmPassword未设置,因此会抛出此错误。这引发了以下问题:

1)如果属性Password被明确地表示为[NotMapped],为什么EF在保存时验证它?2)如果EF在保存期间执行验证,并且在绑定期间也执行相同的操作(即在控制器动作方法中),它不会损害性能吗?(验证两次)3)解决这个错误的建议方法是什么?(如果我显式地将密码属性设置为虚拟值,错误就会消失。)

编辑:我已经删除了代码,因为它很长,可能是没有答案的原因。如果有人想看的话,我可以把它加在下面

如何防止EF在DBContext.SaveChanges()期间验证未映射的属性

EF中的自动验证是一个奇怪的特性——我不喜欢它。您可以阅读本文以了解如何验证所选属性,但我希望您必须手动触发验证,并通过调用

关闭全局验证:
context.Configuration.ValidateOnSaveEnabled = false;

你对NonMappedAttribute的问题很有趣。我没有深入研究EFv4.1中验证的实现,但如果实现是围绕基于数据注释的通用验证的相同规则构建的,它只使用来自ValidationAttribute的属性- NotMappedAttribute不是来自ValidationAttribute

这是这种实现的另一个问题——它结合了映射定义和验证,但这两个特性并不相同,因此不应该由相同的API实现。

@alun删除了他的答案-你的问题的有效答案。您的验证属于视图模型,取决于用户正在执行的操作。它不属于持久模型。为什么?正是因为你当前的问题——持久模型只能容纳单个验证集,并且应用程序中的每个操作都必须确保满足该集的验证标准=你必须确保PasswordConfirmPassword被填充,即使你当前的操作不需要它=>问题

老线程,但由于我面临的EF6完全相同的问题,请允许我分享我的经验,以防有人正在搜索同样的事情。

问题:完全相同:密码&ConfirmPassword 2用户类的[NotMapped]字段。当试图保存新记录时,我得到验证异常,两个字段都是必需的。

调查:我注意到当我更新用户记录时,我没有问题。在搜索不同之处时,我发现我已经覆盖了Validate方法

public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext)

验证MVC模型,EF6显示我的自定义错误消息!瞧!EF6也使用了这个Validate方法!(由于我的代码中的错误,它触发了错误)。

结论:当保存一个实体时,EF6将触发Validate方法,任何'ValidationResult'将阻止保存记录。