我正在尝试在 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 来构建迁移,为您的模型创建初始表集。如果您收到一条错误消息,指出“添加迁移”一词未被识别为 cmdlet 的名称,请关闭并重新打开 Visual Studio。
运行 Update-Database 以将新迁移应用到数据库。此命令在应用迁移之前创建数据库。
使用包管理器控制台的 VS 代码等效项似乎是:
dotnet ef migrations add InitialCreate
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();
}
Fwiw,这些是我对 TodoApi 教程的代码所做的唯一更改,以从内存数据库移动到 LocalDB。
更新: Fwiw,我尝试更改连接字符串中的数据库名称..
string strCxn = "Server=(localdb)\\mssqllocaldb;Database=Contacts2;Trusted_Connection=True;MultipleActiveResultSets=true";
(更改Contacts
为Contacts2
,以防万一它认为,因为它最初找到了联系人数据库,所以迁移已经发生了......)
这也不起作用,尽管错误以一种表明连接字符串正在工作并被读取的方式发生了变化。
Cannot open database "Contacts2" requested by the login. The login failed.
Login failed for user 'COMPUTER-NAME\UserName'.