2

DbSet<T>.Local提供了一个ObservableCollection可以绑定到 WPF 控件的控件。就我而言,我将它绑定到网格。

如果我使用视图模型,我会让它们实现INotifyDataErrorInfoor IDataErrorInfo,然后编写 Fluent Validation 验证器来处理验证。

但在这里我通过DbSet<T>.Local. 我应该如何处理验证?

我应该实施INotifyDataErrorInfo还是IDataErrorInfo在我的模型上实施?

或者有其他选择吗?

4

2 回答 2

2

如果你的应用程序是一个胖客户端,这意味着应用程序的所有层都在一个物理机器上,那么你应该IDataErrorInfo在你的模型上实现。

另一方面,如果您的应用程序是一个瘦多级应用程序,这意味着您的模型是在服务器上实现的,并且您正在使用 WPF 桌面应用程序与服务器端代码进行通信,那么您应该实现INotifyDataErrorInfo.

于 2013-08-02T13:43:08.550 回答
1

是的,我认为在 POCO 模型中实现 IValidatableObject 是有意义的。你可能已经注意到 public ObservableCollection<TEntity> Local { get; }

有几种方法可以做到这一点。所以做一些功课。

作为一些背景,可能有用

然后检查一下

所以我们知道 EF 有触发 Validations 的概念。

Configuration.ValidateOnSaveEnabled = true; 

EF也会调用IEnumerable<ValidationResult> ValidateInstance();

从界面IValidatableObject

如果您的实体 POCO 实施IValidatableObject

EF 将在 SAve 上触发验证。您还可以在需要时轻松触发验证。

这一切都与 UoW 概念巧妙地联系在一起。

 public IEnumerable<DbEntityValidationResult> GetDbValidationErrors() { return 
        Context.GetValidationErrors(); }   // Standard Context call get the problems

可以使用 catch (Exception ex) {.... var x = GetDbValidationErrors(); //....

所以我认为你在正确的轨道上......

编辑:添加 SAMPLE POCOBase 并演示触发器验证。

public interface IFBaseObject : IValidatableObject {
    // a POCO object must implement the VALIDATE method from    IValidatableObject
    bool IsValidInstance();
    IEnumerable<ValidationResult> ValidateInstance();

}

public abstract class BaseObject : IFBaseObject {

     // .... base object stuff removed....

    /// <summary>
    /// Get called every a Validation is trigger on an object.  Here we return and Empty resultset to start with.
    /// If you override ALWAYS call Base first and Continue to add your own results as desired.
    /// Never fail to call base First !
    /// </summary>
    public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
        # region Sample implementation for a POCO thats needs validation

        /* Sample Implementation a sub type POCO might use.
         var validationResult = base.Validate(validationContext).ToList();  

         if (true) // the condition that leads to a validation error
         {
             var memberList = new List<string> { "PropertyName" }; // the name of the offending property
             var error = new ValidationResult("Error text goes here", memberList); // use teh textpool !!! no hardcoded texts
             validationResult.Add(error);
         }

         return validationResult;
       */

        # endregion

        // now back in the base Class.
        var validationResult = new List<ValidationResult>();
        // hand back a list that is empty so errors if any can be added by SUBclasses
        // we can check any Poco that implements a certain interface centrally.  
        var thisIsKeyGuid = this as IFKeyGuid;
        if (thisIsKeyGuid != null) {
            if (thisIsKeyGuid.Id == Guid.Empty) {
                validationResult.Add(new ValidationResult("Id is required", new List<string>() {"Id"}));
            }
        }

        return validationResult;
    }

    /// <summary>
    /// Allows explicit triggering of Validation and returns a TRUE or false answer. Call anytime
    /// </summary>
    /// <returns></returns>
    public virtual bool IsValidInstance() {
        List<ValidationResult> vResults;
        return SelfValidation(out vResults);
    }

    /// <summary>
    /// Calls Self Validation which uses THIS object as the context for validation.
    /// This means you can trigger a validation without first declaring a validation context.
    /// IValidatableObject is effectively called for you. Witch causes "Validate" to be called
    /// </summary>
    /// <returns></returns>
    public IEnumerable<ValidationResult> ValidateInstance() {
        List<ValidationResult> vResults;
        SelfValidation(out vResults);
        return vResults;
    }

    /// <summary>
    /// Although SelfValidation is defined at BaseObject level, this triggers the VALIDATION process on the current Object
    /// see http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validator.aspx for mroe details
    /// So if a POCO Object has overridden  public virtual IEnumerable of ValidationResult Validate(ValidationContext validationContext) 
    /// then this method will be called.  It should of course call :base.Validate
    /// </summary>
    /// <returns>true or false</returns>
    private bool SelfValidation(out List<ValidationResult> vResults) {
        var vc = new ValidationContext(this, null, null);
        vResults = new List<ValidationResult>();
        var isValid = Validator.TryValidateObject(this, vc, vResults, true);
        return isValid;
    }
}
于 2013-08-02T15:57:46.107 回答