在程序集EF6中找不到上下文类型

时间:2017-01-27 18:35:00

标签: entity-framework-6 nopcommerce ef-migrations

我正在开发基于nopCommerce的项目。为了更新自定义实体,我想启用EF迁移。所以我运行以下命令:

jdbc:mysql://ipAddress:3306/tableName

并收到错误:

Enable-Migrations -StartUpProjectName nop.web -ContextProjectName Nop.Plugin.Payments.Deposit -verbose

上下文类定义如下:

Using StartUp project 'Nop.Web'.
System.Data.Entity.Migrations.Infrastructure.MigrationsException: No context type was found in the assembly 'Nop.Plugin.Payments.Deposit'.
   at System.Data.Entity.Utilities.TypeFinder.FindType(Type baseType, String typeName, Func`2 filter, Func`2 noType, Func`3 multipleTypes, Func`3 noTypeWithName, Func`3 multipleTypesWithName)
   at System.Data.Entity.Migrations.Design.ToolingFacade.GetContextTypeRunner.Run()
   at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
   at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
   at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner)
   at System.Data.Entity.Migrations.Design.ToolingFacade.GetContextType(String contextTypeName)
   at System.Data.Entity.Migrations.EnableMigrationsCommand.FindContextToEnable(String contextTypeName)
   at System.Data.Entity.Migrations.EnableMigrationsCommand.<>c__DisplayClass2.<.ctor>b__0()
   at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
No context type was found in the assembly 'Nop.Plugin.Payments.Deposit'.

我已经创建了空项目并在那里启用了迁移。然后我复制并调整了Configuration.cs,看起来像这样:

public class DepositTransactionObjectContext : DbContext, IDbContext
{
    public DepositTransactionObjectContext(string nameOrConnectionString) : base(nameOrConnectionString) { }

    public DepositTransactionObjectContext() { }

    public IList<TEntity> ExecuteStoredProcedureList<TEntity>(string commandText, params object[] parameters) where TEntity : BaseEntity, new()
    {
        throw new System.NotImplementedException();
    }

    public IEnumerable<TElement> SqlQuery<TElement>(string sql, params object[] parameters)
    {
        throw new System.NotImplementedException();
    }

    public int ExecuteSqlCommand(string sql, bool doNotEnsureTransaction = false, int? timeout = null, params object[] parameters)
    {
        throw new System.NotImplementedException();
    }

    public void Detach(object entity)
    {
        throw new System.NotImplementedException();
    }

    public bool ProxyCreationEnabled { get; set; }
    public bool AutoDetectChangesEnabled { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new DepositTransactionMap());

        base.OnModelCreating(modelBuilder);
    }

    public string CreateDatabaseInstallationScript()
    {
        return ((IObjectContextAdapter)this).ObjectContext.CreateDatabaseScript();
    }

    public void Install()
    {
        //It's required to set initializer to null (for SQL Server Compact).
        //otherwise, you'll get something like "The model backing the 'your context name' context has changed since the database was created. Consider using Code First Migrations to update the database"
        Database.SetInitializer<DepositTransactionObjectContext>(null);

        Database.ExecuteSqlCommand(CreateDatabaseInstallationScript());
        SaveChanges();
    }

    public void Uninstall()
    {
        this.DropPluginTable("DepositTransaction");
    }

    public new IDbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity
    {
        return base.Set<TEntity>();
    }
}

但是当我运行Add-Migration时出现以下错误:

namespace Nop.Plugin.Payments.Deposit.Migrations
{
    using Data;
    using System.Data.Entity.Migrations;

    internal sealed class Configuration : DbMigrationsConfiguration<DepositTransactionObjectContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = true;
        }

        protected override void Seed(DepositTransactionObjectContext context)
        {
        }
    }
}

我阅读了很多相同的问题,而且无处不在的原因是Enable-Migrations cmdlet中指定的错误项目(不是具有上下文定义的项目)。但你可以看到,这不是我的情况。

还有什么可能是一个原因?

2 个答案:

答案 0 :(得分:2)

Soooo我设法解决了这个问题。

为了调查,我已经下载了Entity Framework的源代码并检查了异常堆栈中提到的所有方法。在System.Data.Entity.Utilities.TypeFinder.FindType方法中,我找到了这样的指令:

var types = _assembly.GetAccessibleTypes()
                                 .Where(t => baseType.IsAssignableFrom(t));

这导致我在GetAccessibleTypes()方法中找到了这个:

return assembly.DefinedTypes.Select(t => t.AsType());

拥有DefinedTypes是System.Reflection.Assembly类的属性我试图通过在Powershell中加载我的程序集并获取此属性来手动获取此属性:

$a = [System.Reflection.Assembly]::LoadFrom("P:\nopCommerce\Presentation\Nop.Web\Plugins\Payments.Deposit\Nop.Plugin.Payments.Deposit.dll")
$a.DefinedTypes

结果是空虚,因为根本没有类型。

所以我尝试以不同的方式获取类型:

$a.GetTypes()

结果是错误:

  

使用“0”参数调用“GetTypes”的异常:“无法加载一个   或更多所请求的类型。检索LoaderExceptions属性   了解更多信息。“

当我检查LoaderException属性时,我发现了以下内容:

$Error[0].Exception.InnerException.LoaderExceptions
  

无法加载文件或程序集'Autofac,Version = 3.5.0.0,   Culture = neutral,PublicKeyToken = 17863af14b0044da'或其中一个   依赖。该系统找不到指定的文件。不能   加载文件或程序集'Nop.Services,Version = 3.8.0.0,Culture = neutral,   PublicKeyToken = null'或其依赖项之一。系统不能   找到指定的文件。无法加载文件或程序集   'System.Web.Mvc,Version = 5.2.3.0,Culture = neutral,   PublicKeyToken = 31bf3856ad364e35'或其依赖项之一。该   系统找不到指定的文件。无法加载文件或程序集   'System.Web.Mvc,Version = 5.2.3.0,Culture = neutral,   PublicKeyToken = 31bf3856ad364e35'或其依赖项之一。该   系统找不到指定的文件。无法加载文件或程序集   'System.Web.Mvc,Version = 5.2.3.0,Culture = neutral,   PublicKeyToken = 31bf3856ad364e35'或其依赖项之一。该   系统找不到指定的文件。无法加载文件或程序集   'System.Web.Mvc,Version = 5.2.3.0,Culture = neutral,   PublicKeyToken = 31bf3856ad364e35'或其依赖项之一。该   系统找不到指定的文件。

看起来.NET试图加载所有程序集,我的程序集依赖,当然不能,因为它们是共享的,位于别处并由启动项目加载,而不是我的。

所以我已将所有必需的程序集复制到与我相同的文件夹中,并再次尝试启用迁移。这一次没有任何错误!

我问自己,为什么Enable-Migrations不会加载所有这些程序集本身,因为它需要启动项目。但这是一个相当小的问题。

答案 1 :(得分:0)

您还需要添加-ProjectName参数以指定要迁移的位置。例如:

Enable-Migrations -ProjectName Nop.Plugin.Payments.Deposit -StartUpProjectName nop.web -ContextProjectName Nop.Plugin.Payments.Deposit -verbose

它应默认为您在控制台窗口中选择的项目。 https://coding.abel.nu/2012/03/ef-migrations-command-reference/