EF代码第一:如何从Nuget包控制台中看到‘EntityValidationError’属性?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (16)

我为实体框架(4.1.3)代码优先方法定义了类。一

Add-Migration "remigrate" ; Update-Database;

我在包控制台上看到一个错误:一个或多个实体的验证失败。

我的SEED()方法中有一个断点,但是由于我在控制台上运行这个项目,所以我不知道如何获取细节。

我知道我的SEED()方法有一个问题,因为如果我在方法调用之后放一个返回,错误就会消失。那么,如何设置断点,以便查看验证错误是什么?有点迷失了。或者有其他方法在Nuget控制台追踪它??

提问于
用户回答回答于

用部分类定义扩展DBContext类!

如果查看DbContext的类定义,它将如下所示:

// DatabaseContext.cs   -- This file is auto generated and thus shouldn't be changed. 
public partial class [DatabaseContextName] : DbContext { ... }

因此,在另一个文件中,可以创建相同的定义,并覆盖想要的部分。

// partialDatabaseContext.cs  -- you can safely make changes 
// that will not be overwritten in here.
public partial class [DatabaseContextName] : DbContext { // Override defaults here } 

部分类的整体思想-你有没有注意到DbContext是部分类--是可以扩展已生成的类(或将类组织为多个文件),在我们的示例中,我们也希望覆盖SaveChanges方法从添加到DbContext

这样,我们就可以从所有现有的DbContext/SaveChanges调用中获得错误调试信息,而不必更改种子代码或开发代码。

这就是我要做的( the difference is that I just override SaveChanges method in the our own authored DbContext部分等级,而不是生成的)。另外,确保分部类使用正确命名空间否则你会把头撞在墙上。

public partial class Database : DbContext
{
    public override int SaveChanges()
    {
        try
        {
            return base.SaveChanges();
        }
        catch (DbEntityValidationException ex)
        {
            var sb = new StringBuilder();

            foreach (var failure in ex.EntityValidationErrors)
            {
                sb.AppendFormat("{0} failed validation\n", failure.Entry.Entity.GetType());
                foreach (var error in failure.ValidationErrors)
                {
                    sb.AppendFormat("- {0} : {1}", error.PropertyName, error.ErrorMessage);
                    sb.AppendLine();
                }
            }

            throw new DbEntityValidationException(
                "Entity Validation Failed - errors follow:\n" +
                sb.ToString(), ex
                ); // Add the original exception as the innerException
        }
    }
}
用户回答回答于

我通过在SEED方法中的Configuration类中放置一个包装函数来修正它,并将调用替换为SaveChanges而是调用我的函数。此函数将简单地枚举EntityValidationErrors集合,并在异常消息列出个别问题的情况下重新抛出异常。这使得输出显示在NuGet包管理器控制台中。

守则如下:

/// <summary>
/// Wrapper for SaveChanges adding the Validation Messages to the generated exception
/// </summary>
/// <param name="context">The context.</param>
private void SaveChanges(DbContext context) {
    try {
        context.SaveChanges();
    } catch (DbEntityValidationException ex) {
        StringBuilder sb = new StringBuilder();

        foreach (var failure in ex.EntityValidationErrors) {
            sb.AppendFormat("{0} failed validation\n", failure.Entry.Entity.GetType());
            foreach (var error in failure.ValidationErrors) {
                sb.AppendFormat("- {0} : {1}", error.PropertyName, error.ErrorMessage);
                sb.AppendLine();
            }
        }

        throw new DbEntityValidationException(
            "Entity Validation Failed - errors follow:\n" + 
            sb.ToString(), ex
        ); // Add the original exception as the innerException
    }
}

只需将呼叫替换为context.SaveChanges()带着SaveChanges(context)用你的种子法。

扫码关注云+社区