首页 > 代码库 > 自定义ValidateEntity实体验证及DB层面【Interception】拦截EF中的Execute
自定义ValidateEntity实体验证及DB层面【Interception】拦截EF中的Execute
一:ef的注入或者拦截或者扩展
1. DBContext。。。 是否有被注入的点。。。
Controller下面有很多的override行为。。。
《1》 ShouldValidateEntity 是否需要验证实体
触发点: SaveChanges的时候 (CURD)一些操作。
针对这些操作,我们可能会有一些entity的针对性的验证操作。。。
jquery.validator...
mvc中的 binding的操作。【DataAnotation】
《2》 ValidateEntity 具体的验证行为
《3》SaveChange的源代码中进行ShouldValidateEntity角度分析
用ILSpy搞定。。。
// System.Data.Entity.Internal.InternalContext
public virtual int SaveChanges()
{
int result;
try
{
if (this.ValidateOnSaveEnabled)
{
IEnumerable<DbEntityValidationResult> validationErrors = this.Owner.GetValidationErrors();
if (validationErrors.Any<DbEntityValidationResult>())
{
throw new DbEntityValidationException(Strings.DbEntityValidationException_ValidationFailed, validationErrors);
}
}
bool flag = this.AutoDetectChangesEnabled && !this.ValidateOnSaveEnabled;
SaveOptions options = SaveOptions.AcceptAllChangesAfterSave | (flag ? SaveOptions.DetectChangesBeforeSave : SaveOptions.None);
result = this.ObjectContext.SaveChanges(options);
}
catch (UpdateException updateException)
{
throw this.WrapUpdateException(updateException);
}
return result;
}
public IEnumerable<DbEntityValidationResult> GetValidationErrors()
{
List<DbEntityValidationResult> list = new List<DbEntityValidationResult>();
foreach (DbEntityEntry current in this.ChangeTracker.Entries())
{
if (current.InternalEntry.EntityType != typeof(EdmMetadata) && this.ShouldValidateEntity(current))
{
DbEntityValidationResult dbEntityValidationResult = this.ValidateEntity(current, new Dictionary<object, object>());
if (dbEntityValidationResult != null && !dbEntityValidationResult.IsValid)
{
list.Add(dbEntityValidationResult);
}
}
}
return list;
}
三:对StudentName进行验证
protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<object, object> items)
{
//开始做自定义验证: 比如我们的StudentName的值必须不能是“test”。如果是test将会抛出异常
return base.ValidateEntity(entityEntry, items);
}
if (this.ValidateOnSaveEnabled)
{
IEnumerable<DbEntityValidationResult> validationErrors = this.Owner.GetValidationErrors();
if (validationErrors.Any<DbEntityValidationResult>())
{
throw new DbEntityValidationException(Strings.DbEntityValidationException_ValidationFailed, validationErrors);
}
}
四: 在CURD的Database层面进行拦截,进行监控,这样的话方便我们记录log。。。
核心接口: IDbCommandInterceptor
1. 自定义类实现接口
2. 注入到entity framework中。。。通过appconfig的形式。。。
UPDATE [dbo].[Student]
SET [StudentName] = @0
WHERE ([StudentID] = @1)
SELECT [RowVersion]
FROM [dbo].[Student]
WHERE @@ROWCOUNT > 0 AND [StudentID] = @1
记录日志。。。
DataBase.Log 方法。。。。
自定义ValidateEntity实体验证及DB层面【Interception】拦截EF中的Execute