2

我将 EF Database First 与现有的旧数据库一起使用。数据库中几乎每个字段都有一个 maxlength 值,我可以在 .edmx 文件中查看该值。

例如,on of the fields CCSTATUSis nvarchar(20)。当用户输入超过 20 个字符时,它会清除ModelState.IsValid,但会抛出DbEntityValidationExceptionon db.SaveChanges()

对于我添加了 DataAnnotations 的属性,当它们无法验证时,它们会添加模型错误,然后可以将其显示给用户以便进行更正。我知道我可以[MaxLength(n)]为模型元数据类中的所有属性添加属性,但是有没有办法让 EF 添加模型错误而不是DbEntityValidationException在值大于属性的最大长度时抛出?

编辑

谢谢大家的回答。我最终使用EF Power Tools逆向工程师 Code First 功能从我的数据库中生成 Code First 模型,其中包括适当的 maxlength 属性和其他必要的注释。

4

3 回答 3

3

这种行为的原因是 EF 和 ASP.NET MVC 是两个不同的东西。ModelState 是 MVC 的一个概念,它与 EF edmx 元数据无关。如果您想使用相同的类来表示动作输入和域实体,那么您应该使用[MaxLength(n)]属性解决方案。但是,我建议改用 viewmodel/dto。

我不会使用@Reinard 的解决方案(捕获DbEntityValidationException),原因如下:您正在验证输入并且您正在检查控制器操作内的输入验证结果。DbEntityValidationException表示完全不同层(数据库)的问题。这种层层混合迟早会伤害到你。另一个原因是您不应该使用这样的异常,但这是一个不同的主题,例如:为什么不使用异常作为常规控制流?

于 2013-07-29T15:51:27.650 回答
0

为什么不捕获 DbEntityValidationException 并添加模型状态错误?这会将 ModelState.IsValid 设置为 false。

    try
    {
      repo.Save(model);
    }
    catch (DbEntityValidationException ex)
    {
      ModelState.AddModelError("EntityError", ex);
    }

您可以对此进行扩展并创建一个实用方法来记录导致错误的字段:

foreach (var validationErrors in ex.EntityValidationErrors)
{
    foreach (var validationError in validationErrors.ValidationErrors)
    {
        string error = string.Format("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
    }
}

编辑:根据 Peter Porfy 的回答,我同意您应该避免使用异常作为常规控制流程的一部分。理想情况下,您希望使用 [MaxLength(n)] 属性,并且可以修改T4 模板以在生成 pocos 时从数据库中获取它。话虽如此,看到您正在与遗留数据库集成,我假设架构更改可能发生在“新”应用程序(如您正在开发的应用程序)范围之外,这意味着像这样的异常可能会变得更加常见,在在这种情况下,我提供的上述代码示例可能有用。无论您是否需要在每次架构更改时都进行代码更改,或者提前(在某种程度上)迎合这种情况,我相信这完全是一个不同的论点。

于 2013-07-29T15:26:07.023 回答
0

我相信您想要的是修改 T4 模板以自动添加 DataAnnotation。

于 2013-07-29T19:00:43.560 回答