2012-03-06 166 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