Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Entity Framework Custom Constraint

I am currently trying to make a custom constraint with the C# Entity Framework. In more detail:

I have a number field which only can have certain values (for example 1, 2 and 3). How do I achieve this constraint in a code first environment?

like image 607
Simon Schiller Avatar asked Oct 23 '25 16:10

Simon Schiller


1 Answers

Entity Framework automatically validates any validations you add to your model by ValidationAttributes. RequiredAttribute or RangeAttribute are two examples of built-in subclasses of this attribute.

If you want some custom validation, the most convenient way is to piggyback on this mechanism and create you own ValidationAttribute subclass.

If you want to validate a non-contiguous range of values you can't use RangeAttribute but you could make an own attribute, for instance like this:

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);
    }
}

Usage:

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

Note that we have to use fixed values here, because the content of the attribute must be known at compile time. Also, we have to use object because (currently) C# doesn't support generic attributes. Apart from that, there are numerous options. For example, the attribute could also have a method that finds allowed values at runtime, maybe from a named source, so you can supply this name in its constructor.

I don't see any problem in adorning entity classes with validation attributes. The entity model is not a domain model, it's part of a data access layer. It's primary purpose is (and should be) to facilitate an application's data access. If an entity model also happens to support business logic that's a mere bonus.

like image 79
Gert Arnold Avatar answered Oct 25 '25 04:10

Gert Arnold