C# 实体框架上下文验证
当在某些情况下应该应用不同的验证逻辑时,您将如何实现实体框架实体的验证C# 实体框架上下文验证,c#,.net,entity-framework,validation,C#,.net,Entity Framework,Validation,当在某些情况下应该应用不同的验证逻辑时,您将如何实现实体框架实体的验证 例如,如果用户是管理员,则以一种方式验证实体,否则以另一种方式验证。在我听到更明智的想法之前,我会这样做: public partial class MyObjectContext { ValidationContext ValidationContext { get; set; } partial void OnContextCreated() { SavingChanges +=
例如,如果用户是管理员,则以一种方式验证实体,否则以另一种方式验证。在我听到更明智的想法之前,我会这样做:
public partial class MyObjectContext
{
ValidationContext ValidationContext { get; set; }
partial void OnContextCreated()
{
SavingChanges += new EventHandler(EntitySavingChanges);
}
private void EntitySavingChanges(object sender, EventArgs e)
{
ObjectStateManager
.GetObjectStateEntries(EntityState.Added | EntityState.Modified | EntityState.Deleted)
.Where(entry => entry.Entity is IValidatable).ToList().ForEach(entry =>
{
var entity = entry.Entity as IValidatable;
entity.Validate(entry, ValidationContext);
});
}
}
interface IValidatable
{
void Validate(ObjectStateEntry entry, ValidationContext context);
}
public enum ValidationContext
{
Admin,
SomeOtherContext
}
public partial class MyEntity : IValidatable
{
public ValidationContext ValidationContext { get; set; }
public void Validate(ObjectStateEntry entry, ValidationContext context)
{
// this validation doesn't apply to admins
if (context != ValidationContext.Admin)
{
// validation logic here
}
}
}
我将验证属性放在特定于上下文的专用编辑模型上
实体只有适用于所有实体的验证。在我开始讨论如何使用VAB进行验证之前,请允许我说,您必须认真考虑验证规则。虽然可以区分角色之间的验证,但这确实意味着一个角色中的用户保存的对象对另一个用户无效。这意味着具有特定角色的用户可能需要更改该对象,然后才能保存该对象。当同一用户被提升到另一个角色时,也可能发生这种情况。如果您确定要这样做,请继续阅读
这对于企业库(VAB)来说似乎是一项不错的工作,因为它允许对这些复杂场景进行验证。当您想这样做时,忘记基于属性的验证;这根本行不通。您需要基于配置的验证才能使其工作 使用VAB可以做的是使用保存实际验证的配置文件。这在一定程度上取决于实际的验证规则应该是什么,但您可以做的是创建一个基本配置,该配置始终适用于域中的每个对象。然后创建一个或多个只包含扩展验证的配置。例如,假设您有一个
validation\u base.config
文件、一个validation\u manager.config
和一个validation\u admin.config
文件
您可以做的是根据用户的角色将这些验证合并在一起。例如,本例根据配置文件创建了三个配置源:
var base = new FileConfigurationSource("validation_base.config");
var mngr = new FileConfigurationSource("validation_manager.config");
var admn = new FileConfigurationSource("validation_admin.config");
现在您必须将这些文件合并到(至少)两个配置中。一个包含基本+管理器,另一个包含基本+管理规则。虽然合并不是开箱即用的支持,但它将向您展示如何进行合并。使用该文章中的代码时,您将能够执行以下操作:
var managerValidations =
new ValidationConfigurationSourceCombiner(base, mngr);
var adminValidations =
new ValidationConfigurationSourceCombiner(base, admn);
您需要做的最后一件事是将这些验证包装在一个类中,该类根据用户的角色返回正确的集。你可以这样说:
public class RoleConfigurationSource : IConfigurationSource
{
private IConfigurationSource base;
private IConfigurationSource managerValidations;
private IConfigurationSource adminValidations;
public RoleConfigurationSource()
{
this.base = new FileConfigurationSource("validation_base.config");
var mngr = new FileConfigurationSource("validation_manager.config");
var admn = new FileConfigurationSource("validation_admin.config");
managerValidations =
new ValidationConfigurationSourceCombiner(base, mngr);
adminValidations =
new ValidationConfigurationSourceCombiner(base, admn);
}
public ConfigurationSection GetSection(string sectionName)
{
if (sectionName == ValidationSettings.SectionName)
{
if (Roles.UserIsInRole("admin"))
{
return this.adminValidations;
}
else
{
return this.managerValidations;
}
}
return null;
}
#region IConfigurationSource Members
// Rest of the IConfigurationSource members left out.
// Just implement them by throwing an exception from
// their bodies; they are not used.
#endregion
}
现在可以创建一次此RoleConfigurationSource
,您可以在验证对象时提供它,如下所示:
static readonly IConfigurationSource validationConfiguration =
new RoleConfigurationSource();
Validator customerValidator =
ValidationFactory.CreateValidator<Customer>(validationConfiguration);
ValidationResults results = customerValidator.Validate(customer);
if (!results.IsValid)
{
throw new InvalidOperationException(results[0].Message);
}
静态只读IConfigurationSource validationConfiguration=
新角色配置源();
验证器客户验证器=
CreateValidator(validationConfiguration);
ValidationResults=customerValidator.Validate(客户);
如果(!results.IsValid)
{
抛出新的InvalidOperationException(结果[0]。消息);
}
请注意,验证应用程序块不是一个简单的框架。学习它需要一些时间。然而,当您的应用程序足够大时,您的特定需求将证明它的使用是合理的。如果选择VAB,请从读取“”文档开始。如果您有问题,请在某时回来;-)
祝你好运。不管它叫什么,你会怎么做?当有一个实体处于无效状态时,我想有条件地阻止它。当你想看看你的模型是否处于一个业务认为它是有效的状态时,在检查这个模型的过程中,你不会改变这个模型并向用户报告任何错误,在这种情况下,我会考虑你正在做的是验证。不同类型的用户是否有不同的规则并不重要。别忘了标记您最喜欢的答案;-)我喜欢。我不喜欢评论中的最小字符。您可以在此处阅读有关将VAB与实体框架集成的更多信息: