Это похоже на работу для блока приложения проверки библиотеки предприятия (VAB). VAB был разработан для возврата всех ошибок. Кроме того, он не выдает исключение, поэтому вы можете просто попросить его подтвердить тип для вас.
Когда вы решите использовать VAB, я советую вам не использовать методы LINX to SQL OnXXXChanging и OnValidate. Лучше переопределить метод SubmitChange (ConflictMode) в классе DataContext для вызова в API проверки VAB. Это исключает вашу логику проверки из ваших бизнес-сущностей, что делает ваши сущности чистыми.
Посмотрите на следующий пример:
public partial class NorthwindDataContext
{
public ValidationResult[] Validate()
{
return invalidResults = (
from entity in this.GetChangedEntities()
let type = entity.GetType()
let validator = ValidationFactory.CreateValidator(type)
let results = validator.Validate(entity)
where !results.IsValid
from result in results
select result).ToArray();
}
public override void SubmitChanges(ConflictMode failureMode)
{
ValidationResult[] this.Validate();
if (invalidResults.Length > 0)
{
// You should define this exception type
throw new ValidationException(invalidResults);
}
base.SubmitChanges(failureMode);
}
private IEnumerable<object> GetChangedEntities()
{
ChangeSet changes = this.GetChangeSet();
return changes.Inserts.Concat(changes.Updates);
}
}
[Serializable]
public class ValidationException : Exception
{
public ValidationException(IEnumerable<ValidationResult> results)
: base("There are validation errors.")
{
this.Results = new ReadOnlyCollection<ValidationResult>(
results.ToArray());
}
public ReadOnlyCollection<ValidationResult> Results
{
get; private set;
}
}
Вызов метода Validate () вернет коллекцию всех ошибок, но вместо вызова Validate () я бы просто вызвал SubmitChanges (), когда вы будете готовы к сохранению. SubmitChanges () теперь будет проверять ошибки и генерировать исключение, когда один из объектов недействителен. Поскольку список ошибок отправляется в ValidationException, вы можете перебирать ошибки выше стека вызовов и представлять их пользователю следующим образом:
try
{
db.SubmitChanges();
}
catch (ValidationException vex)
{
ShowErrors(vex.ValidationErrors);
}
private static void ShowErrors(IEnumerable<ValidationResult> errors)
{
foreach(var error in errors)
{
Console.WriteLine("{0}: {1}", error.Key, error.message);
}
}
Когда вы используете этот подход, убедитесь, что ваши сущности всегда проверены, прежде чем сохранять их в базе данных
Здесь - хорошая статья, объясняющая, как интегрировать VAB с LINQ to SQL. Вы обязательно должны прочитать его, если хотите использовать VAB с LINQ to SQL.