我目前正在尝试使用C#Entity Framework进行自定义约束。更详细:
我有一个只能有某些值的数字字段(例如1,2和3)。如何在代码优先环境中实现此约束?
答案 0 :(得分:3)
实体框架会自动验证您ValidationAttribute
添加到模型中的所有验证。 RequiredAttribute
或RangeAttribute
是此属性的内置子类的两个示例。
如果你想要一些自定义验证,最方便的方法是搭载这个机制并创建你自己的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