ASP.NET添加迁移问题

时间:2017-08-10 23:10:54

标签: entity-framework asp.net-core entity-framework-core

我从一台PC转移到新PC,我必须重新安装包括VS2017在内的所有内容。但是当我从旧PC运行我的同一个项目到新PC(两个Windows 10)应用程序运行正常。然后我添加了一个新模型,当我运行以下Package Manager控制台命令时,我收到以下错误。

PM> add-migration myMigration -context TestProjContext

错误

  

在启动类'Startup'上调用方法'ConfigureServices'时发生错误。考虑使用IDbContextFactory在设计时覆盖DbContext的初始化。错误:无法在程序集'ef,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = adb9793829ddae60'上找到'UserSecretsIdAttribute'。   在'MyProjContext'上找不到无参数构造函数。将无参数构造函数添加到“MyProjContext”或在“MyProjContext”的同一程序集中添加“IDbContextFactory”的实现。

更新

  1. 此项目已从VS2015升级到VS2017,因此project.json已消失(由.csproj取代。如果我没记错,这是自从转到VS2017以来我第一次运行add-migration命令
  2. Startup.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Logging;
    using TestProj.Data;
    using TestProj.Models;
    using TestProj.Services;
    
    namespace TestProj
    {
        public class Startup
        {
            public Startup(IHostingEnvironment env)
            {
                var builder = new ConfigurationBuilder()
                    .SetBasePath(env.ContentRootPath)
                    .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
    
                if (env.IsDevelopment())
                {
                    // For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
                    builder.AddUserSecrets();
                }
    
                builder.AddEnvironmentVariables();
                Configuration = builder.Build();
            }
    
            public IConfigurationRoot Configuration { get; }
    
            // This method gets called by the runtime. Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
                var connection = @"Server=MyWin10Desktop;Database=MySQL2012Db;Trusted_Connection=True;";
                services.AddDbContext<TestProjContext>(options => options.UseSqlServer(connection));
    
                // Add framework services.
                services.AddDbContext<ApplicationDbContext>(options =>
                    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
    
                services.AddIdentity<ApplicationUser, ApplicationRole>()
                    .AddEntityFrameworkStores<ApplicationDbContext>()
                    .AddDefaultTokenProviders();
    
                services.AddMvc();
                services.AddDistributedMemoryCache();
                services.AddSession();
    
                // Add application services.
                services.AddTransient<IEmailSender, AuthMessageSender>();
                services.AddTransient<ISmsSender, AuthMessageSender>();
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
            {
                loggerFactory.AddConsole(Configuration.GetSection("Logging"));
                loggerFactory.AddDebug();
    
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                    app.UseDatabaseErrorPage();
                    app.UseBrowserLink();
                }
                else
                {
                    app.UseExceptionHandler("/Home/Error");
                }
    
                app.UseStaticFiles();
    
                app.UseIdentity();
                app.UseSession(); //me: must come before app.UseMvc()
    
                // Add external authentication middleware below. To configure them please see http://go.microsoft.com/fwlink/?LinkID=532715
    
                app.UseMvc(routes =>
                {
                    routes.MapRoute(
                        name: "default",
                        template: "{controller=Home}/{action=Index}/{id?}");
                });
            }
        }
    }
    

    更新2

    TestProj.csproj文件:[注意:自应用程序从VS2015升级到VS2017后,升级向导删除了project.json并添加了此{{1}而不是文件

    .csproj

1 个答案:

答案 0 :(得分:0)

相关部分是:

  

MyProjContext上找不到无参数构造函数。将无参数构造函数添加到MyProjContext或在IDbContextFactory

的同一程序集中添加MyProjContext的实现

IDbContextFactory方式是在Entity Framework Core中实现此目的的首选方式,因为您可以使用与Startup.cs中相同的工具。 来自EF Core documentation

  

您还可以提供IDbContextFactory<TContext>的实施。 EF工具可以使用此工厂来创建DbContext的实例。 可能需要这样才能启用特定的设计时体验,例如迁移。   实现此接口以为没有公共默认构造函数的上下文类型启用设计时服务。设计时服务将自动发现与派生上下文在同一程序集中的此接口的实现。

例如:

public class DbContextFactory : IDbContextFactory<MyProjContext>
{
    public MyProjContext Create()
    {
        var environmentName = Environment.GetEnvironmentVariable("Hosting:Environment");
        return Create(Directory.GetCurrentDirectory(), environmentName);
    }

    public MyProjContext Create(DbContextFactoryOptions options)
    {
        return Create(
            options.ContentRootPath,
            options.EnvironmentName);
    }

    public MyProjContext Create(string basePath, string environmentName)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(basePath)
            .AddJsonFile("appsettings.json")
            .AddJsonFile($"appsettings.{environmentName}.json", true)
            .AddEnvironmentVariables();

        var Configuration = builder.Build();

        var connectionName = nameof(MyProjContext);
        var connectionString = Configuration.GetConnectionString(connectionName);
        if (String.IsNullOrWhiteSpace(connectionString) == true)
            throw new InvalidOperationException($"Could not find a connection string named '{connectionName}'.");

        // init SQL server
        var optionsBuilder = new DbContextOptionsBuilder<MyProjContext>();
        optionsBuilder.UseSqlServer(connectionString);

        return new MyProjContext(optionsBuilder.Options);
    }
}