繁体   English   中英

带有ASP.NET Core的代码优先实体框架:初始迁移似乎希望表已经存在

[英]Code First Entity Framework with ASP.NET Core: Initial migration seems to expect tables already exist

我正在尝试在Visual Studio Code中创建一个Code First Entity Framework ASP.NET Core 2项目。 我一直遵循在Linux,macOS和Windows上使用ASP.NET Core MVC和Visual Studio Code创建Web API教程,该教程使用内存中的数据存储作为其DbContext 我正在尝试将其移至LocalDB。

带有新数据库的ASP.NET Core上的EF Core入门教程建议我应该能够通过迁移来做到这一点。

一旦有了模型,就可以使用迁移来创建数据库。

打开PMC:

工具–> NuGet软件包管理器–>软件包管理器控制台

运行Add-Migration InitialCreate以支持迁移以为模型创建初始表集。 如果您收到一条错误消息,指出“ add-migration”一词未被识别为cmdlet的名称,请关闭并重新打开Visual Studio。

运行Update-Database以将新迁移应用于数据库。 此命令在应用迁移之前创建数据库。

与使用Package Manager Console等效的VS Code 似乎是

dotnet ef migrations add InitialCreate

我在EF的Design名称空间中添加了 ...

dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet restore

并在我的csproj中有参考:

<ItemGroup>
    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.1" />
    <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
</ItemGroup>

但是,当我尝试之后执行dotnet ef migrations add命令时,它的作用就像数据库中已经存在的 TodoItems模型的表一样。 据我了解,迁移将基于我的模型创建表。

c:\Projects\TodoApi>dotnet ef migrations add InitialCreate -v
Using project 'c:\Projects\TodoApi\TodoApi.csproj'.
Using startup project 'c:\Projects\TodoApi\TodoApi.csproj'.
Writing 'c:\Projects\TodoApi\obj\TodoApi.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=C:\Users\UserName\AppData\Local\Temp\tmp945E.tmp /verbosity:quiet /nologo c:\Projects\TodoApi\TodoApi.csproj
Writing 'c:\Projects\TodoApi\obj\TodoApi.csproj.EntityFrameworkCore.targets'...
dotnet msbuild /target:GetEFProjectMetadata /property:EFProjectMetadataFile=C:\Users\UserName\AppData\Local\Temp\tmp96FF.tmp /verbosity:quiet /nologo c:\Projects\TodoApi\TodoApi.csproj
dotnet build c:\Projects\TodoApi\TodoApi.csproj /verbosity:quiet /nologo

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:02.29
dotnet exec --depsfile c:\Projects\TodoApi\bin\Debug\netcoreapp2.0\TodoApi.deps.json --additionalprobingpath C:\Users\UserName\.nuget\packages --additionalprobingpath "C:\Program Files (x86)\Microsoft SDKs\NuGetPackagesFallback" --additionalprobingpath "C:\Program Files\dotnet\sdk\NuGetFallbackFolder" --runtimeconfig c:\Projects\TodoApi\bin\Debug\netcoreapp2.0\TodoApi.runtimeconfig.json C:\Users\UserName\.nuget\packages\microsoft.entityframeworkcore.tools.dotnet\2.0.0\tools\netcoreapp2.0\ef.dll migrations add InitialCreate --assembly c:\Projects\TodoApi\bin\Debug\netcoreapp2.0\TodoApi.dll --startup-assembly c:\Projects\TodoApi\bin\Debug\netcoreapp2.0\TodoApi.dll --project-dir c:\Projects\TodoApi\ --verbose --root-namespace TodoApi
Using assembly 'TodoApi'.
Using startup assembly 'TodoApi'.
Using application base 'c:\Projects\TodoApi\bin\Debug\netcoreapp2.0'.
Using working directory 'c:\Projects\TodoApi'.
Using root namespace 'TodoApi'.
Using project directory 'c:\Projects\TodoApi\'.
Finding DbContext classes...
Finding IDesignTimeDbContextFactory implementations...
Finding application service provider...
Finding BuildWebHost method...
Using environment 'Development'.
Using application service provider from BuildWebHost method on 'Program'.
Found DbContext 'DatabaseContext'.
Finding DbContext classes in the project...
fail: Microsoft.EntityFrameworkCore.Database.Command[20102]
      Failed executing DbCommand (7ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
      SELECT CASE
          WHEN EXISTS (
              SELECT 1
              FROM [TodoItems] AS [t])
          THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
      END
System.Data.SqlClient.SqlException (0x80131904): Invalid object name 'TodoItems'.

需要做什么以确保基于我的模型创建表?

我唯一能想到的问题是,我拥有内联连接字符串而不是appsettings.json,但是我不确定为什么这会是一件大事,除非迁移默认情况下正在寻找配置。

public void ConfigureServices(IServiceCollection services)
{
    // In memory: services.AddDbContext<DatabaseContext>(opt => opt.UseInMemoryDatabase("TodoList")); // <<< REMOVED
    string strCxn = "Server=(localdb)\\mssqllocaldb;Database=Contacts;Trusted_Connection=True;MultipleActiveResultSets=true"; // <<< ADDED

    services.AddDbContext<DatabaseContext>(options => options.UseSqlServer(strCxn)); // <<< ADDED
    services.AddMvc();
}

首先,这些是我对TodoApi教程的代码所做的唯一更改,以将其从内存中的数据库迁移到LocalDB。


更新:首先,我尝试更改连接字符串中的数据库名称。

string strCxn = "Server=(localdb)\\mssqllocaldb;Database=Contacts2;Trusted_Connection=True;MultipleActiveResultSets=true";

(将Contacts更改为Contacts2 ,以防万一,因为它最初发现了Contacts数据库,所以已经进行了迁移...)

尽管错误以某种方式表明连接字符串正在工作并且正在被读取,但该错误也没有起作用。

Cannot open database "Contacts2" requested by the login. The login failed.
Login failed for user 'COMPUTER-NAME\UserName'.

作为DbContext构造函数的一部分,我正在播种数据...

public class DatabaseContext : DbContext    {
    public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options)
    {
        this.MinimallySeedDatabase();
    }

    public void MinimallySeedDatabase()
    {
        State NY = this.States.Where(s => s.Abbr.Equals("NY")).FirstOrDefault();
        if (null == NY)
        {
            NY = new State {
                Name = "New York",
                Abbr = "NY"
            };
            this.States.Add(NY);
            this.SaveChanges();
        }

        // etc etc etc...
    }

    public DbSet<Contact> Contacts {get; set;}
    public DbSet<Address> Addresses {get; set;}
    public DbSet<AddyType> AddyTypes {get; set;}
    public DbSet<State> States {get; set;}
}

迁移的执行过程中涉及到的实例DbContext为表之前明显DbSet s的迁移过来。 由于在此示例中,构造函数需要访问状态,并且由于迁移尚未到位,因此它创建了要从中拉出的状态表,因此迁移失败。

正如Kirk 提到的 ,如果我播种,那就很好。 并且,如果您想播种,则需要将其移动到构造函数之外的其他位置,即使构造函数中的播种在迁移尝试之外/在正常的Kestrel测试中也可以正常工作。

对我来说,我只是将其注释掉this.MinimallySeedDatabase(); 当我运行迁移时。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM