我目前正在尝试使用C# Entity Framework创建自定义约束。具体而言:
我有一个数字字段,它只能具有某些特定值(例如1、2和3)。在Code First环境中如何实现此约束?
我目前正在尝试使用C# Entity Framework创建自定义约束。具体而言:
我有一个数字字段,它只能具有某些特定值(例如1、2和3)。在Code First环境中如何实现此约束?
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#不支持泛型属性。除此之外,还有许多选项。例如,属性也可以具有在运行时查找允许值的方法,可能来自命名源,因此您可以在其构造函数中提供此名称。AccountViewModel
是 LoginViewModel
和 RegisterViewModel
的基类。我会在 AccountViewModel
中验证邮箱地址,并将有效数据发送到实体类 ApplicationUser
。或者我错了吗? - Matthias BurgerIValidatableObject
- 我的偏好)可以提供一个很好的最终保护,防止垃圾进入数据库。 - Gert Arnold在领域模型中添加数据注释是非常糟糕的做法,就像D.Mac所写的那样。 那么有没有更好的方法呢?
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?
}
}
}
你可以在属性的setter中做任何想做的事情
仅在前端限制它并不是最好的解决方案,因为你总是可以修改javascript/html - 但你应该向用户显示,他只能插入值1、2或3。同时,在视图模型中使用数据注释进行限制。
或者:
你也可以重写EntityFrameworks的SaveChanges
并添加你的业务逻辑:
public override int SaveChanges(SaveOptions options)
{
foreach (ObjectStateEntry entry in
ObjectStateManager.GetObjectStateEntries(
EntityState.Added | EntityState.Modified))
{
// Validate the objects in the Added and Modified state
// if the validation fails, e.g. throw an exeption.
}
return base.SaveChanges(options);
}