0

私は非常に EF4に新しいです。私は継承、検証に関して数回投稿しましたが、全体の目的はできるだけ書くコードの量を減らすことです。私はObject Contextの操作を大量に扱うPOCOには興味がありません.EFのメリットとコーディングの最小化が必要です。このEF4検証アプローチを検証しますか?

だから、検証の厄介な問題です。この簡略化された例を見てみましょう(DRY Buddiesとdodgy usingsエイリアスを除いて)、これは半分のアプローチのように見えますか?

namespace Model 
{ 
    using Microsoft.Practices.EnterpriseLibrary.Validation.Validators; 
    using DataAnnotations = System.ComponentModel.DataAnnotations; 
    using Validation = Microsoft.Practices.EnterpriseLibrary.Validation; 

    [HasSelfValidation] 
    [DataAnnotations.MetadataType(typeof(PersonValidator))] 
    public partial class Person 
    { 
     [SelfValidation] 
     public Validation.ValidationResults Validate() 
     { 
      var validationResults = Validation.Validation.Validate(this); 

      if (string.IsNullOrEmpty(this.LastName) || this.LastName.Length > 4) 
      { 
       validationResults.AddResult(new Validation.ValidationResult("This is a test error message for a custom validation error.", this, null, null, null)); 
      } 

      return validationResults; 
     } 
    } 

    [HasSelfValidation] 
    public class PersonValidator 
    { 
     [NotNullValidator(MessageTemplate = "First Name must be supplied.")] 
     [ContainsCharactersValidator("Rcd", ContainsCharacters.All, MessageTemplate = "{1} must contains characters \"{3}\" ({4}).")] 
     [StringLengthValidator(5, 50, MessageTemplate = "{1} (\"{0}\") must be between {3} ({4}) and {5} ({6}) characters in length.")] 
     public string FirstName { get; set; } 

     [NotNullValidator(MessageTemplate = "Last Name must be supplied.")] 
     [ContainsCharactersValidator("Wes", ContainsCharacters.All, MessageTemplate = "{1} must contains characters \"{3}\" ({4}).")] 
     [StringLengthValidator(5, 50, MessageTemplate = "{1} (\"{0}\") must be between {3} ({4}) and {5} ({6}) characters in length.")] 
     public string LastName { get; set; } 
    } 
} 

これについてはかなり冷静です。私は、上記のような呼び出すことができます。

var validationResults = person.Validate(); 

をしかし、私はいくつかの基本的なチェックをしたい場合、私は、検証()、[SelfValidation]のものを取り除くの属性を維持し、そしてちょうど呼び出すことができます。

var validationResults = Validation.Validate(person); 

私は必要なだけの検証を含めるだけで、web.configにゼロ設定があります。

私のジブのカットはいかがですか? :)

リチャード

+0

個人的には、あなたのモデルで「長さ」のようなものを検証する必要はありません。これは*入力*の検証です。これはプレゼンテーション層で行う必要があります。最後の検証はEF自身が行います。これは、基礎となるデータベース制約(例えば、NVARCHAR(4) - フィールドが4文字以上にならないようにします)に対してフィールドを検証します。あなたのアプリケーションのどの時点で 'person.Validate'を呼び出すでしょうか? – RPM1984

+0

私が言ったように、簡単な例です。例としてコード化するのに時間がかかりすぎる、現実世界の検証を伴う現実世界のアプリケーションのコンテキストでそれを想像してみてください。 – Richard

+0

私は次のように(再び簡単に!)呼び出すと思います:using(var context = new ModelContainer()){var person = new Person(); var validationResults = Validation.Validate(人); if(validationResults.IsValid){context.AddToPeople(person); } else {WriteValidationResults(validationResults);} }}しかし、EFのものはまだ私にとって新しいものなので、 – Richard

答えて

1

私は個人的には、エンティティ自体に直接コード内で直接検証を呼び出し、そして特にないのファンではありません。 Validateに電話してくれるところがたくさんあり、Validateに電話するのを忘れやすいです。代わりに、ObjectContextが、変更されたすべてのエンティティに対して自動的に基礎となる検証フレームワークを呼び出させ、検証エラーが発生したときに特別な例外(プレゼンテーション層で捕捉可能)をスローします。

これは、ObjectContext.SavingChangesイベントにフックし、そこでトリガーの検証を行うことで実行できます。

public partial class ModelContainer 
{ 
    partial void OnContextCreated() 
    { 
     this.SavingChanges += 
      (sender, e) => Validate(this.GetChangedEntities()); 
    } 

    private IEnumerable<object> GetChangedEntities() 
    { 
     const EntityState AddedAndModified = 
      EntityState.Added | EntityState.Modified; 

     var entries = this.ObjectStateManager 
      .GetObjectStateEntries(AddedAndModified); 

     return entries.Where(e => e != null); 
    } 

    private static void Validate(IEnumerable<object> entities) 
    { 
     ValidationResults[] invalidResults = (
      from entity in entities 
      let type = entity.GetType() 
      let validator = ValidationFactory.CreateValidator(type) 
      let results = validator.Validate(entity) 
      where !results.IsValid 
      select results).ToArray(); 

     if (invalidResults.Length > 0) 
      throw new ValidationException(invalidResults); 
    }  
} 

あなたはそれhereについての詳細を読むことができますを次のようにあなたの部分ObjectContextを書くことができます。

+0

私はそれが少し古いことを知っています。しかし、これはとても良いアプローチです+1 –

関連する問題