是否有另一种方法可以为LINQ-to-SQL模型类创建合约?

时间:2009-06-24 00:59:04

标签: asp.net-mvc linq-to-sql model repository

对于本示例,我有两个类,它们是针对LINQ-to-SQL模型类的部分类。

public partial class Foo 
{
    public bool IsValid 
    {
        get { return (GetRuleViolations().Count() == 0); }
    }

    public IEnumerable<RuleViolation> GetRuleViolations() 
    {
        yield break;
    }

    partial void OnValidate(ChangeAction action) 
    {
        if (!IsValid)
            throw new ApplicationException("Rule violations prevent saving");
    }
}

public partial class Bar 
{
    public bool IsValid 
    {
        get { return (GetRuleViolations().Count() == 0); }
    }

    public IEnumerable<RuleViolation> GetRuleViolations() 
    {
        yield break;
    }

    partial void OnValidate(ChangeAction action) 
    {
        if (!IsValid)
            throw new ApplicationException("Rule violations prevent saving");
    }
}

我想将此功能考虑在内以消除冗余逻辑。我尝试使用IModel接口,然后使用扩展方法进行合同,但它与部分类分解。

我最终得到了这个:

    public class ModelBase
    {
        public bool IsValid
        {
            get
            {
                return this.GetRuleViolations().Count() == 0;
            }
        }

        public void OnValidate(ChangeAction action)
        {
            if (!IsValid) throw new ApplicationException("Rule violations prevent saving");
        }

        public virtual IEnumerable<RuleViolation> GetRuleViolations() { return null; }
    }

public partial class Blog : ModelBase
{
    partial void OnValidate(ChangeAction action)
    {
        base.OnValidate(action);
    }

    public override IEnumerable<RuleViolation> GetRuleViolations()
    {
        // rules omitted
    }
}

我应该这样做吗?谢谢。

1 个答案:

答案 0 :(得分:1)

我唯一要补充的是你可能想要定义一个接口,然后是实现接口的各种基类来提供一些默认验证。例如,您可能有一个基类,它对字符串属性进行XSS验证,验证它们不包含任何HTML。使用接口将允许您从任何这些基类派生(或者甚至只是接口,如果您需要),并且仍然能够将它们视为接口。您可能还考虑使用允许指定ChangeAction的签名 - 您可能对Delete有不同的验证规则而不是Update或Insert。

public interface IValidatedEntity
{
    IEnumerable<RuleViolations> GetRuleViolations();
    IEnumerable<RuleViolations> GetRuleViolations( ChangeAction action );
}

public abstract class XSSValidatedEntity : IValidatedEntity
{
    public virtual IEnumerable<RuleViolations> GetRuleViolations()
    {
        return GetRuleViolations( ChangeAction.Insert );
    }

    public virtual IEnumerable<RuleViolations> GetRuleViolations( ChangeAction action )
    {
         if (action != ChangeAction.Delete)
         {
             return ValidateStringProperties();
         }
         return new List<RuleViolations>();
    }
}