2013-02-06 75 views
1

我所有的實體都從IValidatableObject繼承。我遇到的問題是當我保存一個實體並且這個實體包含一個引用另一個未完全加載的實體的屬性時(它不爲空,但只包含帶有引用關鍵字的對象),代碼會引發錯誤。錯誤是該屬性(引用另一個實體)沒有正確驗證。這是真的,因爲對象只包含ID。讓我通過一個小例子向您展示我在說什麼:實體框架如何使驗證僅發生在實體上而不發生在底層實體

public class Exercise : BaseModel 
{ 
    public LocalizedString Name { get; set; } 
    public virtual Muscle Muscle { get; set; } 

    public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
    { 
     if (Name == null) 
     { 
      yield return new ValidationResult("Name is mandatory", new[] { "Name" }); 
      yield break; 
     } 

     if (Name.French == null || Name.French.Length < 3) 
     { 
      yield return new ValidationResult("Exercise's French name must be over 3 characters"); 
     } 

     if (Name.English == null || Name.English.Length < 3) 
     { 
      yield return new ValidationResult("Exercise's English name must be over 3 characters"); 
     } 

     if (Muscle == null) 
     { 
      yield return new ValidationResult("Exercice must be assigned to a muscle"); 
     } 
    } 
} 

public class Muscle : BaseModel 
{ 
    public LocalizedString Name { get; set; } 
    public ICollection<Exercise> Exercises { get; set; } 
    public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
    { 
     if (Name == null) 
     { 
      yield return new ValidationResult("Name is mandatory", new[] { "Name" }); 
      yield break; 
     } 

     if (Name.French == null || Name.French.Length < 3) 
     { 
      yield return new ValidationResult("Muscle's French name must be over 3 characters"); 
     } 

     if (Name.English == null || Name.English.Length < 3) 
     { 
      yield return new ValidationResult("Muscle's English name must be over 3 characters"); 
     } 
    } 
} 

//--- This is the code into the repository: 
public int Insert(Exercise entity) 
{ 
    if (entity.Muscle != null) 
    { 
     var localExercise = DatabaseContext.Set<Muscle>().Local.SingleOrDefault(e => e.Id == entity.Muscle.Id); 
     if (localExercise != null) 
     { 
      DatabaseContext.Set<Muscle>().Attach(entity.Muscle); 
     } 
    } 

    DatabaseContext.Set<Exercise>().Add(entity); 
    return DatabaseContext.SaveChanges(); 
} 

我正在保存練習。練習包含一個名稱,肌肉設置有一個有效的ID,但不包含任何名稱。這就是爲什麼,當我保存時,驗證發生在Entity Framework內部,告訴我該名稱是Muscle對象所必需的。

我不需要肌肉滿載,因爲我只是想附上這一個。我不想在裏面鍛鍊屬性「MuscleID」。我真的想要這個結構。

任何人都可以告訴我我需要做什麼才能使驗證只發生在保存的實體上,而不是發生在異物上?

回答

0

您應該在控制器和視圖之間使用ViewModel。這樣你可以保持你的模型不存在。比使用AutoMapper將ViewModel屬性映射到控制器中的回發模型。 ViewModel可以定義你的驗證規則並實現IValidatableObject。你也可以定義你所有的ViewModel都沒有底層實體。這會讓多餘的實體和屬性超出您的視野。確保在if(ModelState.IsValid)檢查後使用AutoMapper將ViewModel映射到模型。

+0

我有ViewModel。這不是問題。問題是關於模型的IValidatableObject。當保存模型時,EF會自動調用接口進行驗證。 –