我非常是EF4的新手。我已经发布了几次关于继承,验证的帖子,但我的总体目标是尽可能减少我编写的代码量。我对POCO感兴趣,大量的ObjectContext摆弄:我想要EF的好处和最少的编码。
所以,棘手的验证问题。看看这个简化的例子,(除了DRY伙伴和狡猾的使用别名),这看起来像是一个不太合适的方法吗?
namespace Model
{
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
using DataAnnotations = System.ComponentModel.DataAnnotations;
using Validation = Microsoft.Practices.EnterpriseLibrary.Validation;
[HasSelfValidation]
[DataAnnotations.MetadataType(typeof(PersonValidator))]
public partial class Person
{
[SelfValidation]
public Validation.ValidationResults Validate()
{
var validationResults = Validation.Validation.Validate(this);
if (string.IsNullOrEmpty(this.LastName) || this.LastName.Length > 4)
{
validationResults.AddResult(new Validation.ValidationResult("This is a test error message for a custom validation error.", this, null, null, null));
}
return validationResults;
}
}
[HasSelfValidation]
public class PersonValidator
{
[NotNullValidator(MessageTemplate = "First Name must be supplied.")]
[ContainsCharactersValidator("Rcd", ContainsCharacters.All, MessageTemplate = "{1} must contains characters \"{3}\" ({4}).")]
[StringLengthValidator(5, 50, MessageTemplate = "{1} (\"{0}\") must be between {3} ({4}) and {5} ({6}) characters in length.")]
public string FirstName { get; set; }
[NotNullValidator(MessageTemplate = "Last Name must be supplied.")]
[ContainsCharactersValidator("Wes", ContainsCharacters.All, MessageTemplate = "{1} must contains characters \"{3}\" ({4}).")]
[StringLengthValidator(5, 50, MessageTemplate = "{1} (\"{0}\") must be between {3} ({4}) and {5} ({6}) characters in length.")]
public string LastName { get; set; }
}
}
有一些相当酷的事情。我可以这样称呼以上内容:
var validationResults = person.Validate();
但是,如果我只想要一些基本的检查,我可以删除Validate(),[SelfValidation]的东西,保留属性,然后只需调用:
var validationResults = Validation.Validate(person);
我只需要包含尽可能多的验证,并且在web.config中有ZERO配置。
我的副臂怎么样? :)
理查德
答案 0 :(得分:1)
我个人不是直接在代码中调用验证的粉丝,特别是不直接在实体本身。您会拨打Validate
很多地方,很容易忘记致电Validate
。相反,让ObjectContext
自动为所有已更改的实体调用底层验证框架,并在发生验证错误时抛出一个特殊异常(可以在表示层中捕获)。
您可以通过挂钩ObjectContext.SavingChanges
事件并在那里触发验证来完成此操作。您可以按如下方式编写部分ObjectContext
:
public partial class ModelContainer
{
partial void OnContextCreated()
{
this.SavingChanges +=
(sender, e) => Validate(this.GetChangedEntities());
}
private IEnumerable<object> GetChangedEntities()
{
const EntityState AddedAndModified =
EntityState.Added | EntityState.Modified;
var entries = this.ObjectStateManager
.GetObjectStateEntries(AddedAndModified);
return entries.Where(e => e != null);
}
private static void Validate(IEnumerable<object> entities)
{
ValidationResults[] invalidResults = (
from entity in entities
let type = entity.GetType()
let validator = ValidationFactory.CreateValidator(type)
let results = validator.Validate(entity)
where !results.IsValid
select results).ToArray();
if (invalidResults.Length > 0)
throw new ValidationException(invalidResults);
}
}
您可以详细了解here。