2012-03-06 118 views
9

我正在使用Entity Framework 4.3进行代码优先开发,并且似乎没有可能通过属性注释或其他任何方式表示CHECK constraint。我看到EF 5.0将会增加对checking enumerations的支持,但这并不完全是我在这之后所做的。是否可以表达检查约束?

为了给出一个简化的例子,我想验证所有Person对象的名字都是“Bob”或“Harry”,并且都是5,10或30岁。

public class Person 
{ 
    [Required] 
    [Check("Bob", "Harry")] //yes, this attribute is imaginary 
    public string FirstName { get; set; } 

    [Required, Check(5, 30, 50)] //check is still imaginary 
    public int Age { get; set; } 
} 

我可以运行ALTER脚本事后添加这些限制,我可以推出自己的check属性来进行验证,但有什么办法,我缺少真正表达的非列举CHECK约束实体框架?

回答

3

你可以自己写一个(未经测试):

public class CheckAttribute : System.ComponentModel.DataAnnotations.ValidationAttribute 
{ 
    object[] ValidValues; 

    public CheckAttribute<T>(params T[] validValues) 
    { 
     ValidValues = validValues; 
    } 

    public override bool IsValid(object value) 
    { 
     return ValidValues.FirstOrDefault(v => v.Equals(value)) != null; 
    } 
} 
+0

我写我自己的检查属性(看起来极其相似你的),但我的问题在于这是一个仅限于域的属性 - 它并没有在支持表实体中反映出来,同时也有一个检查约束,就像字符串的MaxLength被反映到表结构中一样。 – 48klocs 2012-03-06 18:47:08

+1

我并不是那么熟悉EF,但是我在ILSpy中打开了'EntityFramework.dll',它看起来像'System.Data.Entity.Internal.Validation.EntityValidatorBuilder'负责分析属性并决定如何处理他们。看起来'RequiredAttribute','MaxLengthAttribute','StringLengthAttribute'和'DisplayAttribute'基本上被硬连线到数据库创建过程中。我不确定是否有可能像现在一样对EF进行如下操作。 – 2012-03-06 18:58:59

4

我一直想要把检查的限制,虽然有几个方法可以做到像由M.这里给出的答案Babcock并使用初始化程序中的ExecuteSql手动向数据库添加约束。

但我认为最简单的方法是使用正则表达式注释,所以在你的榜样,你会去:

<!-- language: c# --> 
public class Person 
{ 
    [Required] 
    [RegularExpression(@"Bob|Harry")] 
    public string FirstName { get; set; } 

    [Required, RegularExpression(@"5|30|50")] 
    public int Age { get; set; } 
} 
+0

这只有在您的检查约束可以通过正则表达式验证时才有效。这适用于OP的//简化示例。在其他情况下,@ M.Babcock描述的自定义验证将会很有用。 – 2014-10-30 13:35:35