EF ValidationContext:如何知道是否正在创建或更新实体

时间:2015-08-21 22:25:41

标签: c# entity-framework validation asp.net-mvc-4

在MVC中为实体进行自定义验证我实现了IValidatableObject接口。

现在,在验证代码中,我希望在创建实体时执行某些操作,如果正在更新,则需要执行其他操作。以下面的代码作为我想要的例子:

public partial class ActividadProyecto : IValidatableObject
    {

        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            if (IsBeingCreated)
            {
                // Do stuff
            }
            else if(IsBeingUpdated)
            {
                // Do other stuff
            }
        }
}

有可能吗?我搜索了很多,并没有接近这个。我找到的唯一解决方案是为Create进程创建一个ViewModel,为Update进程创建另一个进程,然后为它们创建独立的验证器:这只是疯狂的错误和丑陋。

提前致谢!

2 个答案:

答案 0 :(得分:4)

通过覆盖ValidateEntity()中的DbContext方法,您可以通过Validate()字典对象将所需信息传递给实体的validationContext.Items方法。

的DbContext:

public class YourDbContext : DbContext
{
    // other code

    protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<object, object> items)
    {
        items["is_data_layer"] = true;
        items["is_insert"] = this.Entry(entityEntry.Entity).State == EntityState.Added;
        return base.ValidateEntity(entityEntry, items);
    }
}

来自您实体的用法:

public partial class ActividadProyecto : IValidatableObject
{
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        object dummy;

        // skip logic if "Validate" is not called from EF...
        if (validationContext.Items.TryGetValue("is_data_layer", out dummy))
        {
            if ((bool)validationContext.Items["is_insert"]) // insert mode
            {
                // Do stuff
            }
            else // update mode
            {
                // Do other stuff
            }
        }
    }
}

修改

我承认我从纯粹的EF(数据层)角度回答。我不是ASP.NET MVC专家。但正如mo.esmp指出的那样,如果您还将EF实体用作&#34;视图模型&#34;,那么MVC框架将调用Validate()方法来验证视图层中的实体。只有之后,EF才会调用Validate方法。这样就可以解释为什么您的实体的Validate方法在上下文的ValidateEntity方法之前被称为

那么,问题就变成了:您对增加的逻辑感兴趣的是哪种验证?是否要将逻辑添加到&#34;视图层&#34;验证?或者你想在&#34;数据层中应用你的逻辑&#34; (EF)验证?

我没有足够的细节来回答这个问题。但是如果你只需要在&#34;数据层中添加你的逻辑&#34; (EF)验证阶段,然后我调整了上面的示例代码,如果EF没有调用验证,则跳过逻辑。你可以尝试一下。

答案 1 :(得分:1)

当您将表单发布到服务器时,ASP.NET MVC模型绑定器会尝试绑定FormActividadProyecto实体,并且将执行IValidatableObject.Validate方法以验证您的模型,但是您尝试保存实体,将执行EF ValidateEntity方法。所以在IValidatableObject.Validate方法中,您无法确定天气实体是否已创建或更新,因为它发生在EF ValidateEntity方法之前。