2013-07-29 64 views
1

我对现有的旧数据库使用EF数据库优先。几乎每个字段在数据库中都有一个maxlength值,我可以在.edmx文件中查看该值。实体框架数据库首先自动验证属性的最大长度

例如,字段CCSTATUSnvarchar(20)。当用户输入超过20个字符时,它将清除ModelState.IsValid,但会在db.SaveChanges()上抛出DbEntityValidationException

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

编辑

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

+0

我不知道有什么简单的方法来做到这一点,但你可以检查这个[link](http://www.headspring.com/entity-framework-code-first-dbcontext-validation/),并且看看它是否有帮助 – Nilesh

回答

2

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

我不会@Reinard的,原因如下解决方案(捕捉DbEntityValidationException)去:您要验证输入和正在检查的控制器动作内输入验证的结果。 DbEntityValidationException表示完全不同的图层(数据库)存在问题。这种混合层迟早会伤害你。另一个原因是,你不应该使用这样的例外,但这是一个不同的主题,例如:Why not use exceptions as regular flow of control?

+0

谢谢彼得,我已经修改了我的原始答案,将您的想法纳入此 –

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); 
    } 
} 

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

0

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

相关问题