【问题标题】:what would cause EF Code First IDatabaseInitializer InitializeDatabase to not get called?什么会导致 EF Code First IDatabaseInitializer InitializeDatabase 不被调用?
【发布时间】:2011-12-07 23:34:51
【问题描述】:

我有一个自定义初始化设置如下:

public class PromptIfChangesNeededDBInitializer : IDatabaseInitializer<MeyerREContext>
{

    public PromptIfChangesNeededDBInitializer()
    {  // This constructor is called properly

    }

    #region IDatabaseInitializer<TContext> Members


    public void InitializeDatabase(MeyerREContext context)
    { // This is never called

       ... Code that checks existence and seeds etc

    }

 }

这是我的 DbContext 类

public class MeyerREContext : DbContext
{
    static MeyerREContext()
    {
        Database.SetInitializer(new PromptIfChangesNeededDBInitializer());
    }

    public DbSet<Address> Addresses { get; set; }
    ... More DbSet property definitions


protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

       modelBuilder.Configurations.Add(new AddressMap());
      ... More Configurations 

    }

}

这是对上下文的第一次调用

City city = dbNew.Cities.Where(e=>e.CityName=="Foley").FirstOrDefault();

Initializer 的构造函数在断点确认后被正确调用,OnModelCreating 在断点确认后正常运行,但在 OnModelCreating 完成后,InitializeDatabase 永远不会被调用...

在对上下文进行任何调用之前,我从 DBContext 的 ctor 中删除了 Database.SetInitializer(new PromptIfChangesNeededDBInitializer()) 调用到调用类的 ctor 中,现在我的行​​为略有不同:

public class CreateData
{

    private VFPModelContainer db = new VFPModelContainer();
    private MeyerREContext dbNew;

    public CreateData()
    {
        Database.SetInitializer(new PromptIfChangesNeededDBInitializer<MeyerREContext>());

        dbNew = new MeyerREContext();
        dbNew.Database.Initialize(force: true);   NUll Exception here now...

    }

现在在 EF 框架代码中生成一个空异常:

这里是异常详情:

System.NullReferenceException occurred
Message=Object reference not set to an instance of an object.
Source=EntityFramework
StackTrace:
   at    
    System.Data.Entity.ModelConfiguration.Configuration.Properties.Navigation.NavigationPropertyConfiguration.ValidateConsistency(NavigationPropertyConfiguration navigationPropertyConfiguration)

内部异常:

看起来异常发生在 EntityTypeConfiguration 调用之一中,但异常被某种方式吞没了?我怎样才能弄清楚它是哪个电话?该模型中大约有 100 个实体...

如何获取有关 EF 内部问题的更多信息?我需要知道哪个导航属性有问题...我认为问题在于 EF 正在创建后台工作线程来创建和验证模型,但我不明白为什么异常很模糊??

有什么想法吗?

谢谢 格雷格

【问题讨论】:

  • 在您真正访问数据库(执行查询或保存更改)之前,不会调用初始化程序。
  • 对不起,我漏掉了那部分,我会编辑它,它试图在第一次调用上下文时创建模型等...
  • 您的第一个代码(使用静态构造函数)应该可以正常工作。你确定你没有得到异常并且异常在你的代码中被捕获并以某种方式被忽略吗? InitializeDatabase 被称为 OnModelCreating。您是否检查了是否使用断点到达OnModelCreating 的末尾?如果没有,请跳过添加配置的 100 行,看看它在哪里中断。
  • 是的,我已经确认它无一例外地通过了所有配置......异常发生在 OnModelCreating 的最后一行和 InitializeDatabase 调用之前......所以它在某处名为 NavigationPropertyConfiguration.ValidateConsistency(NavigationPropertyConfiguration navigationPropertyConfiguration) 的方法中的 EF 代码它是一个空引用异常...如何从该异常中获取有关哪个导航属性导致问题的更多异常详细信息?

标签: entity-framework c#-4.0


【解决方案1】:

必须安装 Reflector 并反编译 EF 程序集才能找出问题所在:

这是导致问题的行...

private void ValidateConsistency(NavigationPropertyConfiguration navigationPropertyConfiguration)
{
  if ((navigationPropertyConfiguration.InverseEndKind.HasValue && this.EndKind.HasValue) && (navigationPropertyConfiguration.InverseEndKind != this.EndKind))
  {
    throw System.Data.Entity.ModelConfiguration.Resources.Error.ConflictingMultiplicities(this.NavigationProperty.Name, this.NavigationProperty.ReflectedType);
  }
  if ((navigationPropertyConfiguration.EndKind.HasValue && this.InverseEndKind.HasValue) && (navigationPropertyConfiguration.EndKind != this.InverseEndKind))
  {
    throw System.Data.Entity.ModelConfiguration.Resources.Error.ConflictingMultiplicities(this.InverseNavigationProperty.Name, this.InverseNavigationProperty.ReflectedType);
  }

在我的情况下,InverseNavigationProperty 属性为 null,这会导致 EF 试图抛出异常时出现异常...

根本问题是我定义了反向属性关系,但没有为它定义映射...

但是,无法确定是哪个实体导致了此问题...此方法中的这些检查应使用 try catch 进行包装以避免此问题,以便它们可以向最终用户抛出更有意义的错误...

谢谢 格雷格

【讨论】:

    猜你喜欢
    • 2010-12-02
    • 1970-01-01
    • 1970-01-01
    • 2013-04-06
    • 1970-01-01
    • 2012-04-11
    • 1970-01-01
    • 1970-01-01
    • 2011-09-11
    相关资源
    最近更新 更多