ci*_*ess 17 .net c# migration entity-framework crud
我不明白有什么问题。我试图用一个非常简单的模型在 .net core mvc 中制作一个简单的 crud,该模型几乎没有字段。
这些是我的模型:
public class Employee
{
[Key] public int EmployeeId { get; set; }
[Required] public string FistName { get; set; }
[Required] public string LastName { get; set; }
public int PositionId { get; set; }
public virtual Position Position { get; set; }
}
public class Position
{
[Key]
public int PositionId { get; set; }
public string PositionName { get; set; }
public ICollection<Employee> Employees { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
然后我制作了应用程序上下文:
public class EmployeeContext : DbContext
{
public EmployeeContext(DbContextOptions<EmployeeContext> options)
: base(options)
{
}
public DbSet<Employee> Employees { get; set; }
public DbSet<Position> Positions { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Employee>()
.HasOne(e => e.Position)
.WithMany()
.HasForeignKey(e => e.PositionId);
}
}
Run Code Online (Sandbox Code Playgroud)
并在 Startup.cs 中注册上下文:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDbContext<EmployeeContext>(item =>item.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
Run Code Online (Sandbox Code Playgroud)
可能还需要一个 .csproj 和 program.cs 的文件代码
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net461</TargetFramework>
<DebugType>full</DebugType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.CookiePolicy" Version="2.2.8" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer.Design" Version="1.1.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Logging.Configuration" Version="3.1.2" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.1" />
</ItemGroup>
</Project>
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
Run Code Online (Sandbox Code Playgroud)
然后我尝试先迁移,但我看到一个非常奇怪的错误 Add-Migration FirstInit -verbose
Using project 'Crud'.
Using startup project 'Crud'.
Build started...
Build succeeded.
C:\.nuget\packages\microsoft.entityframeworkcore.tools\3.1.2\tools\net461\win-x86\ef.exe migrations add FirstInit --json --verbose --no-color --prefix-output --assembly C:\source\repos\Crud\Crud\bin\Debug\net461\Crud.exe --startup-assembly C:\source\repos\Crud\Crud\bin\Debug\net461\Crud.exe --project-dir C:\source\repos\Crud\Crud\ --language C# --working-dir C:\source\repos\Crud --root-namespace Crud
Using assembly 'Crud'.
Using startup assembly 'Crud'.
Using application base 'C:\source\repos\Crud\Crud\bin\Debug\net461'.
Using working directory 'C:\source\repos\Crud\Crud'.
Using root namespace 'Crud'.
Using project directory 'C:\source\repos\Crud\Crud\'.
Using configuration file 'C:\source\repos\Crud\Crud\bin\Debug\net461\Crud.exe.config'.
Using assembly 'Crud'.
Using startup assembly 'Crud'.
Using application base 'C:\source\repos\Crud\Crud\bin\Debug\net461'.
Using working directory 'C:\source\repos\Crud\Crud'.
Using root namespace 'Crud'.
Using project directory 'C:\source\repos\Crud\Crud\'.
Finding DbContext classes...
Finding IDesignTimeDbContextFactory implementations...
Finding application service provider...
Finding Microsoft.Extensions.Hosting service provider...
Using environment 'Development'.
System.TypeLoadException: There is no implementation of the GetItem method in the type "Microsoft.AspNetCore.Mvc.Razor.Internal.FileProviderRazorProjectFileSystem" from assembly "Microsoft.AspNetCore.Mvc.Razor, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60".
? Microsoft.Extensions.DependencyInjection.MvcRazorMvcCoreBuilderExtensions.AddRazorViewEngineServices(IServiceCollection services)
? Microsoft.Extensions.DependencyInjection.MvcRazorMvcCoreBuilderExtensions.AddRazorViewEngine(IMvcCoreBuilder builder)
? Microsoft.Extensions.DependencyInjection.MvcServiceCollectionExtensions.AddMvc(IServiceCollection services)
? Crud.Startup.ConfigureServices(IServiceCollection services) ? C:\source\repos\Crud\Crud\Startup.cs:?????? 38
--- End the stack trace from the previous location where the exception occurred ---
? System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
? Microsoft.AspNetCore.Hosting.ConventionBasedStartup.ConfigureServices(IServiceCollection services)
? Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureApplicationServices()
? Microsoft.AspNetCore.Hosting.Internal.WebHost.Initialize()
? Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
An error occurred while accessing the Microsoft.Extensions.Hosting services. Continuing without the application service provider. Error: There is no implementation of the GetItem method in the type "Microsoft.AspNetCore.Mvc.Razor.Internal.FileProviderRazorProjectFileSystem" from assembly "Microsoft.AspNetCore.Mvc.Razor, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60".
No application service provider was found.
Finding DbContext classes in the project...
Found DbContext 'EmployeeContext'.
Microsoft.EntityFrameworkCore.Design.OperationException: Unable to create an object of type 'EmployeeContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728 ---> System.MissingMethodException:There are no parameterless constructors defined for this object..
? System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
? System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
? System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
? System.Activator.CreateInstance(Type type, Boolean nonPublic)
? System.Activator.CreateInstance(Type type)
? Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.<>c__DisplayClass13_3.<FindContextTypes>b__13()
--- End trace of internal exception stack ---
? Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.<>c__DisplayClass13_3.<FindContextTypes>b__13()
? Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(Func`1 factory)
? Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType)
? Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType)
? Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType)
? Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_0.<.ctor>b__0()
? Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
? Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Unable to create an object of type 'EmployeeContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
Run Code Online (Sandbox Code Playgroud)
这3行有什么问题?
She*_*ari 26
EF 在不运行 Main 的情况下调用 CreateWebHostBuilder 或 BuildWebHost。所以 Iconfiguration 为空。
创建从IDesignTimeDbContextFactory继承的新类。
public class YourDbContext : DbContext
{
//Dbcontext implementation
}
public class YourDbContextFactory : IDesignTimeDbContextFactory<YourDbContext>
{
public YourDbContext CreateDbContext(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder<YourDbContext>();
optionsBuilder.UseSqlServer("your connection string");
return new YourDbContext(optionsBuilder.Options);
}
}
Run Code Online (Sandbox Code Playgroud)
您正在使用使用 IHostBuilder 的新 .net 核心 EF。(在像您这样的旧版本中,提供程序是 IWebHostBuilder)。这些工具首先尝试通过调用 Program.CreateHostBuilder(),调用 Build(),然后访问 Services 属性来获取服务提供者。您可以从此处了解有关设计时 DbContext 创建的更多信息
它可能是由于您的启动文件中的条件或在您注射时发生的。例如,您有一个标志来检查 appsetting 中的某个变量是否为真以使用内存数据库实例。
EF 需要在不启动应用程序的情况下构建模型并使用 DbContext。当 EF 调用方法时,您的配置服务仍然为空,这就是您收到错误的原因。
确保你已经安装了这个包
Microsoft.EntityFrameworkCore.Tools
小智 9
我对这个特定错误的体验与在 powershell 中运行以及没有为 ASPNETCORE_ENVIRONMENT 设置适当的环境变量有关。
$env:ASPNETCORE_ENVIRONMENT = "Development"
Run Code Online (Sandbox Code Playgroud)
然后:
添加-迁移...
更新-数据库...
等等...
正如已接受的答案所示:
EF 调用 CreateWebHostBuilder 或 BuildWebHost 而不运行 Main。所以 Iconfiguration 为空。
但您可以通过重写来使用这个简单的解决方案,而不是使用更复杂的工厂OnConfiguring。
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext() {
}
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer("Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=Chinook");
}
}
Run Code Online (Sandbox Code Playgroud)
*注意不要在源代码中使用数据库连接字符串(文档)
dotnet user-secrets set ConnectionStrings:Chinook "Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Chinook"
dotnet ef dbcontext scaffold Name=ConnectionStrings:Chinook Microsoft.EntityFrameworkCore.SqlServer
Run Code Online (Sandbox Code Playgroud)
还要注意在cli命令行中只能使用一个\。
小智 8
我的错误是
访问 Microsoft.Extensions.Hosting 服务时出错。在没有应用程序服务提供商的情况下继续。错误:值不能为空。(参数“path”)无法创建“MainDbContext”类型的对象。有关设计时支持的不同模式,请参阅https://go.microsoft.com/fwlink/?linkid=851728
运行您的应用程序一次。如果出现运行时启动错误,您将收到此错误。
对我来说,我有一项服务从 appSettings 读取路径,但我忘记提供 appSettings 中的值。因此,在应用程序启动时发生了空异常。