5

我有一个复杂的类(参见下面的示例代码),我保存在 Entity Framework Code First 数据库 (V5) 中。问题是如果在保存到数据库的 FooAndOrBar 数据中使用了 FooClass,我想阻止 FooClass 条目被删除。因为它可能为空,所以外键检查不会阻止 FooClass 被删除,所以我必须检查自己。

    class FooClass { ... some properties }

    class BarClass { ... some properties }

    class FooAndOrBar
    {
        public int Id { get; set; }
        public FooClass Foo { get; set; }
        public BarClass Bar { get; set; }
    }

因此,按照验证跨越多个数据库条目的条目的良好做法,我向 Entity Framework 的 ValidateEntity 方法添加了一个测试,如下所示。

    protected override DbEntityValidationResult ValidateEntity(
        DbEntityEntry entityEntry, IDictionary<object, object> items)
    {
        if (entityEntry.Entity is FooClass && 
            entityEntry.State == EntityState.Delete)
        {               
            if (... entityEntry.Entity is used in DbContext.FooAndOrBars ...)
                return new DbEntityValidationResult(... error ...);
        }

        return base.ValidateEntity(entityEntry, items);

    }

问题是 ValidateEntity 似乎没有在删除时被调用。这是有道理的(为什么要验证您要删除的内容),但给我留下了我应该把支票放在哪里的问题?我确实使用了 UnitOfWork/repository 模式,并且可以在其中进行测试,但那很臭。

有没有其他人遇到过这个问题并以干净的方式解决了它?您的意见将不胜感激。

帕维尔的回答(见下文)。

@pawel 指出您可以覆盖 ShouldValidateEntity 以便为已删除的项目调用 ValidateEntity。这是一些示例代码,以防其他人发现这很有用。

/// <summary>
/// Override ShouldValidateEntity to cause deleted entities to be checked as well
/// </summary>
protected override bool ShouldValidateEntity(DbEntityEntry entityEntry)
{
    if (entityEntry.State == EntityState.Deleted)
        return true;

    return base.ShouldValidateEntity(entityEntry);
}

实际上,我通过检查实体的类型使检查比所有已删除的项目更严格,但这只是为了提高性能。

4

1 回答 1

11

默认情况下,仅验证修改和添加的实体。这可以通过重写该DbContext.ShouldValidateEntity()方法来更改,以对已删除的实体也返回 true。

于 2013-08-06T15:38:24.067 回答