C#实体框架自定义约束

时间:2016-10-21 10:09:24

标签: c# entity-framework

我目前正在尝试使用C#Entity Framework进行自定义约束。更详细:

我有一个只能有某些值的数字字段(例如1,2和3)。如何在代码优先环境中实现此约束?

2 个答案:

答案 0 :(得分:3)

实体框架会自动验证您ValidationAttribute添加到模型中的所有验证。 RequiredAttributeRangeAttribute是此属性的内置子类的两个示例。

如果你想要一些自定义验证,最方便的方法是搭载这个机制并创建你自己的ValidationAttribute子类。

如果您要验证不连续的值范围,则无法使用RangeAttribute,但您可以创建自己的属性,例如:

public class AllowedValuesAttribute : ValidationAttribute
{
    private readonly ICollection<object> _validValues;
    private readonly Type _type;

    public AllowedValuesAttribute(Type type, object[] validValues)
    {
        _type = type;
        _validValues = validValues.Where(v => v != null && v.GetType() == type).ToList();
    }

    public override bool IsValid(object value)
    {
        return value.GetType() == _type && _validValues.Contains(value);
    }

    public override string FormatErrorMessage(string name)
    {
        return string.Format("Value for '{0}' is not an allowed value", name);
    }
}

用法:

[AllowedValues(typeof(int), new object[] { 1, 2, 4, 8, 16 })]
public int Base { get; set; }

请注意,我们必须在此处使用固定值,因为必须在编译时知道属性的内容。此外,我们必须使用object,因为(目前)C#不支持通用属性。除此之外,还有很多选择。例如,该属性还可以有一个方法,可以在运行时查找允许的值,也许来自命名源,因此您可以在其构造函数中提供此名称。

我在使用验证属性装饰实体类时没有看到任何问题。实体模型是域模型,它是数据访问层的一部分。它的主要目的是(并且应该)促进应用程序的数据访问。如果实体模型也恰好支持业务逻辑,那只是一种奖励。

答案 1 :(得分:0)

在D.Mac写道,在域模型中添加数据注释是非常糟糕的做法。 那么以更好的方式做到这一点呢?

RewriteEngine On

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L,NE]

你可以在你的财产制定者中做任何你想做的事情

并且只在前端限制它不是最好的解决方案,因为你总是可以修改javascript / html - 但是你应该向用户显示他只能插入值1,2或3。 还要在带有数据注释的viewmodel中对其进行限制。

OR:

您还可以覆盖EntityFrameworks public MyClass { private int myNumberField; public int MyNumberField { get { return myNumberField; } set { if (value >= 1 && value <=3) myNumberField = value; else // throw exception? // set default-value (maybe 1)? // do nothing? } } } 并添加您的businesslogic:

SaveChanges