将ASP.NET Core 2.1与实体框架的类库分开

时间:2018-11-15 15:09:23

标签: c# asp.net-core entity-framework-core asp.net-core-2.1 entity-framework-core-migrations

阅读此问题时,您认为这是一个重复的问题,并且我没有进行足够的搜索来找到此问题的解决方案。不幸的是,我花了很多时间寻找这个问题的解决方案。我正在开发一个ASP.NET Core 2.1应用程序,该应用程序主要由ASP.NET Web APP和Entity Framework Core组成。

我正在使用代码优先方法来添加迁移和更新数据库,并且一切看起来都很好,直到我将asp.net核心Web应用程序与Entity Framework Core分离了。实际上,我将EntityFrameworkCore放在单独的类库中。 当我尝试使用

添加新迁移时
dotnet ef migrations add InitialCreate

我遇到了这个错误

  

在类“ Program”上访问IWebHost时发生错误。没有应用程序服务提供商就继续进行。错误:无法从程序集“ ef,版本= 2.1.4.0,文化=中性,PublicKeyToken = adb9793829ddae60”中加载类型“ EF.EFCore.ApplicationDbContext”。   System.TypeLoadException:无法从程序集“ EF,版本= 1.0.0.0,区域性=中性,PublicKeyToken =空”中加载类型“ EF.EFCore.ApplicationDbContext”。      在System.Reflection.CustomAttribute._CreateCaObject(RuntimeModule pModule,IRuntimeMethodInfo pCtor,字节** ppBlob,字节* pEndBlob,Int32 * pcNamedArgs)处      在System.Reflection.CustomAttribute.CreateCaObject(RuntimeModule模块,IRuntimeMethodInfo ctor,IntPtr&blob,IntPtr blobEnd,Int32&namedArgs)      在System.Reflection.CustomAttribute.GetCustomAttributes处(RuntimeModule装饰模块,Int32装饰MetadataToken,Int32 pcaCount,RuntimeType attributeFilterType,布尔值mustBeInheritable,IList派生属性)      在System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeType类型,RuntimeType caType,布尔值继承)      在System.Attribute.GetCustomAttributes(MemberInfo元素,类型,布尔值继承)      在System.Attribute.GetCustomAttribute(MemberInfo元素,类型attributeType,布尔值继承)      在System.Reflection.CustomAttributeExtensions.GetCustomAttribute [T](MemberInfo元素)      在Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations。<> c.b__12_5(TypeInfo t)      在System.Linq.Enumerable.WhereSelectListIterator 2.MoveNext() at System.Linq.Enumerable.WhereEnumerableIterator 1.MoveNext()      在System.Linq.Enumerable.ConcatIterator 1.MoveNext() at System.Linq.Enumerable.DistinctIterator 1.MoveNext()      在System.Linq.Enumerable.WhereEnumerableIterator 1.MoveNext() at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.FindContextTypes() at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.FindContextType(String name) at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType) at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_1.<.ctor>b__0() at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0 1.b__0()处      在Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action操作)   无法从程序集“ EF,版本= 1.0.0.0,文化=中性,PublicKeyToken =空”中加载类型“ EF.EFCore.ApplicationDbContext”。

我确信问题与项目分离成组件形式有关

services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(conString,builder => builder.MigrationsAssembly(typeof(Startup).Assembly.FullName)));

上面的代码是我用于从IdentityContext派生的ApplicationDBContext类的代码,无论添加还是删除MigrationAssembly,这都没有什么不同。另外,添加IDbContextFactory没什么大不了的 我将从IdentityContext派生的ApplicationDbContext更改为以下

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    // Entity
    string conString = "Server=(local); Database=OnlineStoreDB;User Id=sa;Password=123@asu;";

    optionsBuilder.UseSqlServer(conString, x => x.MigrationsAssembly("EF"));

    base.OnConfiguring(optionsBuilder);
    // base.OnConfiguring(optionsBuilder);
    //if (!optionsBuilder.IsConfigured)
    //{
    //    optionsBuilder.UseSqlServer(conString);
    //}
    //else
    //{
    //    optionsBuilder.UseSqlServer(conString);
    //}

}

1 个答案:

答案 0 :(得分:0)

我们的方法是创建一个具有以下内容的小型帮助程序类库:

public class ApiDbContextMigrationsFactory : IDesignTimeDbContextFactory<ApiDbContext>
{
    public ApiDbContext CreateDbContext(string[] args)
    {
        var optionsBuilder = new DbContextOptionsBuilder<ApiDbContext>();
        optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Api.Local.Migration;Trusted_Connection=True;ConnectRetryCount=0",
            b => b.MigrationsAssembly(typeof(ApiDbContext).Assembly.FullName));

        return new ApiDbContext(optionsBuilder.Options);

    }
}

然后我们使用以下命令从HelperForMigrations-Library-Folder内部创建迁移:

dotnet ef migrations add nameofMigration --startup-project ./ --project ../ApiDbContextProject --context ApiDbContext