【问题标题】:ASP.NET Add-migration issueASP.NET 添加迁移问题
【发布时间】:2018-01-19 08:28:46
【问题描述】:

我从一台 PC 转移到一台新 PC,在那里我必须重新安装所有东西,包括 VS2017。但是当我从旧 PC 到新 PC(都是 Windows 10)运行我的同一个项目时,应用程序运行良好。然后我添加了一个新模型,当我运行以下包管理器控制台命令时,我收到以下错误。

PM> add-migration myMigration -context TestProjContext

错误

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

更新

  1. 该项目已从 VS2015 升级到 VS2017,因此 project.json 消失了(被 .csproj 取代。如果我没记错的话,这是自迁移到 VS2017 以来我第一次运行 add-migration 命令

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 并添加了此 .csproj 文件

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp1.1</TargetFramework>
    <PreserveCompilationContext>true</PreserveCompilationContext>
    <AssemblyName>ABCTest</AssemblyName>
    <OutputType>Exe</OutputType>
    <PackageId>ABCTest</PackageId>
    <UserSecretsId>aspnet-ABCTest-6af8ade3-87ff-4468-a9ce-8bb69c696ab8</UserSecretsId>
    <RuntimeFrameworkVersion>1.1.1</RuntimeFrameworkVersion>
    <PackageTargetFallback>$(PackageTargetFallback);dotnet5.6;portable-net45+win8</PackageTargetFallback>
  </PropertyGroup>

  <ItemGroup>
    <None Remove="Properties\PublishProfiles\ABCTestP.pubxml" />
    <None Remove="Properties\PublishProfiles\FolderProfile.pubxml" />
    <None Remove="Properties\PublishProfiles\FolderProfile1.pubxml" />
  </ItemGroup>

  <ItemGroup>
    <None Update="wwwroot\**\*;Views\**\*;Areas\**\Views">
      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
    </None>
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="bootstrap" Version="2.3.2" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="1.1.1" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="1.0.0" />
    <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="1.1.1" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer.Design" Version="1.1.1" />
    <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="1.1.1" />
    <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="1.1.1" />
    <PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="1.1.1" />
    <PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration.Tools" Version="1.1.0-preview4-final" />
    <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.1" />
    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="1.1.1" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.1.1" />
    <PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="1.1.1" />
    <PackageReference Include="Microsoft.Extensions.Logging" Version="1.1.1" />
    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="1.1.1" />
    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.1" />
    <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="1.1.1" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="1.1.0">
      <PrivateAssets>All</PrivateAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.AspNetCore.Session" Version="1.1.1" />
    <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="1.1.1" />
    <PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="1.1.0" />
    <PackageReference Include="BundlerMinifier.Core" Version="2.3.327" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="1.1.2" />
    <PackageReference Include="EPPlus.Core" Version="1.4.0" />
  </ItemGroup>

 <ItemGroup>
    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.0" />
  </ItemGroup>

</Project>

【问题讨论】:

  • 你可能正在点击这个github.com/aspnet/Announcements/issues/209
  • @Smit 我认为你让我走上了正确的道路。我刚刚在上面的更新部分添加了item 1。在我将我的 Web 项目从 VS2015 移动到 VS2017 之后,错误就开始了。由于我不再拥有project.json,我应该关注链接的哪个部分(您提供的)?
  • 您使用的是哪个版本的软件包?分享您的 csproj 文件。
  • @Smit 我刚刚在我的帖子的 UPDATE 2 中添加了您要求的文件。
  • 那个 csproj 不包含任何引用。你能成功构建吗?你在哪里引用 EF Core 包?

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


【解决方案1】:

相关部分是这样的:

MyProjContext 上找不到无参数构造函数。要么向MyProjContext 添加无参数构造函数,要么在与MyProjContext 相同的程序集中添加IDbContextFactory 的实现

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

您还可以提供IDbContextFactory&lt;TContext&gt; 的实现。 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);
    }
}

【讨论】:

  • 感谢您的帮助。我刚刚将我的Startup.cs 文件添加到我上面的原始帖子中,以便您或其他人可以帮助我了解我需要在 Startup.cs 文件中做什么。根据我从阅读其他在线文章中收集到的信息,我需要以某种方式创建您的 DbContextFactory 课程。这将是 Model 文件夹下的独立类吗?另外,您的意思是您的班级名称是TestProjContextFactory ,而不是DbContextFactory,如MSDN example
  • 我尝试了您的建议,但收到了我发布的错误 here。我可能缺少什么?
猜你喜欢
  • 2010-10-05
  • 2019-06-19
  • 2021-05-15
  • 2019-03-03
  • 2022-12-12
  • 2020-10-23
  • 1970-01-01
  • 2012-09-25
  • 1970-01-01
相关资源
最近更新 更多