使用ADO.NET实体框架拦截实体保存

时间:2021-07-12 02:15:17

I want to invoke a validation function inside the entities objects right before they are stored with ObjectContext#SaveChanges(). Now, I can keep track of all changed objects myself and then loop through all of them and invoke their validation methods, but I suppose an easier approach would be implement some callback that ObjectContext will invoke before saving each entity. Can the latter be done at all? Is there any alternative?

我想在实体对象内部使用ObjectContext#SaveChanges()存储验证函数。现在,我可以自己跟踪所有已更改的对象,然后循环遍历所有这些对象并调用它们的验证方法,但我想更简单的方法是实现ObjectContext在保存每个实体之前将调用的一些回调。后者可以完成吗?还有其他选择吗?

2 个解决方案

#1


I've figured out how. Basically, we can intercept SavingChanges event of ObjectContext and loop through the newly added/modified entities to invoke their validation function. Here's the code I used.

我已经弄明白了。基本上,我们可以拦截ObjectContext的SavingChanges事件并循环通过新添加/修改的实体来调用它们的验证函数。这是我使用的代码。

    partial void OnContextCreated()
    {
        SavingChanges += PerformValidation;
    }

    void PerformValidation(object sender, System.EventArgs e)
    {
        var objStateEntries = ObjectStateManager.GetObjectStateEntries(
            EntityState.Added | EntityState.Modified);

        var violatedRules = new List<RuleViolation>();
        foreach (ObjectStateEntry entry in objStateEntries)
        {
            var entity = entry.Entity as IRuleValidator;
            if (entity != null)
                violatedRules.AddRange(entity.Validate());
        }
        if (violatedRules.Count > 0)
            throw new ValidationException(violatedRules);
    }

#2


Well, you could do it that way, but it means that you're allowing your clients to directly access the ObjectContext, and, personally, I like to abstract that away, in order to make the clients more testable.

好吧,你可以这样做,但这意味着你允许你的客户直接访问ObjectContext,而且,就我个人而言,我喜欢抽象它,以使客户端更容易测试。

What I do is use the repository pattern, and do the validation when save is called on a repository.

我所做的是使用存储库模式,并在存储库上调用save时进行验证。

#1


I've figured out how. Basically, we can intercept SavingChanges event of ObjectContext and loop through the newly added/modified entities to invoke their validation function. Here's the code I used.

我已经弄明白了。基本上,我们可以拦截ObjectContext的SavingChanges事件并循环通过新添加/修改的实体来调用它们的验证函数。这是我使用的代码。

    partial void OnContextCreated()
    {
        SavingChanges += PerformValidation;
    }

    void PerformValidation(object sender, System.EventArgs e)
    {
        var objStateEntries = ObjectStateManager.GetObjectStateEntries(
            EntityState.Added | EntityState.Modified);

        var violatedRules = new List<RuleViolation>();
        foreach (ObjectStateEntry entry in objStateEntries)
        {
            var entity = entry.Entity as IRuleValidator;
            if (entity != null)
                violatedRules.AddRange(entity.Validate());
        }
        if (violatedRules.Count > 0)
            throw new ValidationException(violatedRules);
    }

#2


Well, you could do it that way, but it means that you're allowing your clients to directly access the ObjectContext, and, personally, I like to abstract that away, in order to make the clients more testable.

好吧,你可以这样做,但这意味着你允许你的客户直接访问ObjectContext,而且,就我个人而言,我喜欢抽象它,以使客户端更容易测试。

What I do is use the repository pattern, and do the validation when save is called on a repository.

我所做的是使用存储库模式,并在存储库上调用save时进行验证。