This solution, which I came up with for this situation, simply checks the table for writing with a different identifier that has the same value for the property being checked. It is assumed that you will use LinqToSQL and that any table that requires such verification has one identifier column.
I would also set a unique restriction on the base table in the database. This attribute allows me to add a good error message to the form and associate it with the corresponding property.
public class UniqueAttribute : ValidationAttribute { public Func<DataContext> GetDataContext { get; private set; } public string IDProperty { get; private set; } public string Message { get; private set; } public UniqueAttribute(Type dataContextType, string idProperty, string message) { IDProperty = idProperty; Message = message; GetDataContext = () => (DataContext)Activator.CreateInstance(dataContextType); } public UniqueAttribute(Type dataContextType, string idProperty, string message, string connectionString) { IDProperty = idProperty; Message = message; GetDataContext = () => (DataContext)Activator.CreateInstance(dataContextType, new object[] { connectionString }); } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var idProperty = validationContext.ObjectType.GetProperty(IDProperty); var idType = idProperty.PropertyType; var id = idProperty.GetValue(validationContext.ObjectInstance, null);
Usage example:
[MetadataType(typeof(UserMetadata))] public partial class Group : IDatabaseRecord { public class UserMetadata { [Required(ErrorMessage = "Name is required")] [StringLength(255, ErrorMessage = "Name must be under 255 characters")] [Unique(typeof(MyDataContext), "GroupID", "Name must be unique")] public string Name { get; set; } } }
daveb
source share