.Net 核心 Web API 与 EF
.Net Core Web API with EF
我对 .Net Core 和 Entity Framework 都是全新的。我正在尝试通过遵循一些教程来学习这两种技术,但我正在努力。我的 Web API 项目有两个控制器 - 向导生成 ValuesController.cs,在创建新的 Core Web API 项目时创建,我添加的第二个控制器称为 FilesController.cs。
我的appsettings.json:
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"ConnectionStrings": {
" \"PropWorxConnection\"": "server=a.b.com;user id=propworx;persistsecurityinfo=True;database=abcde;password=12345"
}
}
我的Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using MySQL.Data.EntityFrameworkCore.Extensions;
namespace PropWorxAPI
{
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)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddDbContext<Models.PropWorxDbContext>(options =>
options.UseMySQL(Configuration.GetConnectionString("PropWorxConnection")));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseMvc();
}
}
}
一个简单的模型:
namespace PropWorxAPI.Models
{
[Table("files")]
public partial class File
{
public int ID { get; set; }
public string FileNum { get; set; }
}
}
我的背景:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using MySQL.Data.EntityFrameworkCore.Extensions;
namespace PropWorxAPI.Models
{
public class PropWorxDbContext : DbContext
{
private readonly string _connectionString;
public PropWorxDbContext(string connectionString)
{
_connectionString = connectionString;
}
public PropWorxDbContext(DbContextOptions<PropWorxDbContext> options) : base(options)
{
}
public DbSet<Models.File> Files { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Models.File>().ToTable("Files");
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseMySQL(_connectionString);
base.OnConfiguring(optionsBuilder);
}
}
}
和我的控制器:
using Microsoft.AspNetCore.Mvc;
using PropWorxAPI.Models;
namespace PropWorxAPI.Controllers
{
[Route("api/[controller]")]
public class FilesController : Controller
{
private readonly PropWorxDbContext _context;
public FilesController(PropWorxDbContext context)
{
_context = context;
}
[HttpGet]
public string Get()
{
return "Controller Working!!!";
}
}
}
现在,当我 运行 它 (F5) 时,它会打开 Edge 并转到 http://localhost:51932/api/values。这将显示此输出:
["value1","value2"]
所以它默认为 ValuesController(我该如何更改它???)。无论如何,重要的是自动生成的 ValuesController 有效。我现在手动更改 URL 以指向我创建的 FilesController,即
http://localhost:51932/api/files
...我明白了:
HTTP 500 错误
奇怪...网站无法显示此页面
现在,如果我从我的 FilesController 中删除上下文参数 - 即我从:
public FilesController(PropWorxDbContext context)
{
_context = context;
}
到
public FilesController()
{
}
然后它工作并正确显示:
这是文件控制器
知道为什么吗?谢谢,抱歉过于冗长 post...
从 OnConfiguring
方法中删除这两行。
optionsBuilder.UseMySQL(_connectionString);
base.OnConfiguring(optionsBuilder);
您已经在 startup.cs
的 ConfigureServices
方法中告诉提供者
services.AddDbContext<Models.PropWorxDbContext>(options =>
options.UseMySQL(Configuration.GetConnectionString("PropWorxConnection")));
已更新 DbContext
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using MySQL.Data.EntityFrameworkCore.Extensions;
namespace PropWorxAPI.Models
{
public class PropWorxDbContext : DbContext
{
public PropWorxDbContext(DbContextOptions<PropWorxDbContext> options) : base(options)
{
}
public DbSet<Models.File> Files { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Models.File>().ToTable("Files");
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
}
}
}
您的依赖项注入无效。当框架试图创建一个新的 FilesController 时,它不能,因为它不知道 PropWorxContext 是什么。
namespace PropWorxAPI.Models
{
public class PropWorxDbContext : DbContext
{
private readonly string _connectionString;
//public PropWorxDbContext(string connectionString)
//{
// _connectionString = connectionString;
//}
public PropWorxDbContext(DbContextOptions<PropWorxDbContext> options) : base(options)
{
}
public DbSet<Models.File> Files { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Models.File>().ToTable("Files");
}
//protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
//{
// optionsBuilder.UseMySQL(_connectionString);
// base.OnConfiguring(optionsBuilder);
//}
}
}
您不需要连接字符串或 OnConfiguring 覆盖,因为您正在 Startup.cs
中执行这些操作
public void ConfigureServices(IServiceCollection services)
{
// This must come before MVC
services.AddDbContext<Models.PropWorxDbContext>(options => options.UseMySQL(Configuration.GetConnectionString("PropWorxConnection")));
services.AddMvc();
}
services.AddDbContext 行使用依赖注入注册您的数据库。这使您的控制器能够使用正确的构造函数工作
public FilesController(PropWorxDbContext context)
{
_context = context;
}
我认为您遇到的唯一问题是 DbContext 中不必要的代码,这会阻止依赖项注入容器更新它。
弄清楚了 - 我在 appsettings.json 中的 ConnectionStrings 格式不正确(我有一些奇怪的正斜杠 - 不知道为什么......感谢 Ahmar 和 user1900799 的帮助 - 非常感谢!
我对 .Net Core 和 Entity Framework 都是全新的。我正在尝试通过遵循一些教程来学习这两种技术,但我正在努力。我的 Web API 项目有两个控制器 - 向导生成 ValuesController.cs,在创建新的 Core Web API 项目时创建,我添加的第二个控制器称为 FilesController.cs。
我的appsettings.json:
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"ConnectionStrings": {
" \"PropWorxConnection\"": "server=a.b.com;user id=propworx;persistsecurityinfo=True;database=abcde;password=12345"
}
}
我的Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using MySQL.Data.EntityFrameworkCore.Extensions;
namespace PropWorxAPI
{
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)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddDbContext<Models.PropWorxDbContext>(options =>
options.UseMySQL(Configuration.GetConnectionString("PropWorxConnection")));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseMvc();
}
}
}
一个简单的模型:
namespace PropWorxAPI.Models
{
[Table("files")]
public partial class File
{
public int ID { get; set; }
public string FileNum { get; set; }
}
}
我的背景:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using MySQL.Data.EntityFrameworkCore.Extensions;
namespace PropWorxAPI.Models
{
public class PropWorxDbContext : DbContext
{
private readonly string _connectionString;
public PropWorxDbContext(string connectionString)
{
_connectionString = connectionString;
}
public PropWorxDbContext(DbContextOptions<PropWorxDbContext> options) : base(options)
{
}
public DbSet<Models.File> Files { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Models.File>().ToTable("Files");
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseMySQL(_connectionString);
base.OnConfiguring(optionsBuilder);
}
}
}
和我的控制器:
using Microsoft.AspNetCore.Mvc;
using PropWorxAPI.Models;
namespace PropWorxAPI.Controllers
{
[Route("api/[controller]")]
public class FilesController : Controller
{
private readonly PropWorxDbContext _context;
public FilesController(PropWorxDbContext context)
{
_context = context;
}
[HttpGet]
public string Get()
{
return "Controller Working!!!";
}
}
}
现在,当我 运行 它 (F5) 时,它会打开 Edge 并转到 http://localhost:51932/api/values。这将显示此输出:
["value1","value2"]
所以它默认为 ValuesController(我该如何更改它???)。无论如何,重要的是自动生成的 ValuesController 有效。我现在手动更改 URL 以指向我创建的 FilesController,即
http://localhost:51932/api/files
...我明白了:
HTTP 500 错误 奇怪...网站无法显示此页面
现在,如果我从我的 FilesController 中删除上下文参数 - 即我从:
public FilesController(PropWorxDbContext context)
{
_context = context;
}
到
public FilesController()
{
}
然后它工作并正确显示:
这是文件控制器
知道为什么吗?谢谢,抱歉过于冗长 post...
从 OnConfiguring
方法中删除这两行。
optionsBuilder.UseMySQL(_connectionString);
base.OnConfiguring(optionsBuilder);
您已经在 startup.cs
ConfigureServices
方法中告诉提供者
services.AddDbContext<Models.PropWorxDbContext>(options =>
options.UseMySQL(Configuration.GetConnectionString("PropWorxConnection")));
已更新 DbContext
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using MySQL.Data.EntityFrameworkCore.Extensions;
namespace PropWorxAPI.Models
{
public class PropWorxDbContext : DbContext
{
public PropWorxDbContext(DbContextOptions<PropWorxDbContext> options) : base(options)
{
}
public DbSet<Models.File> Files { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Models.File>().ToTable("Files");
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
}
}
}
您的依赖项注入无效。当框架试图创建一个新的 FilesController 时,它不能,因为它不知道 PropWorxContext 是什么。
namespace PropWorxAPI.Models
{
public class PropWorxDbContext : DbContext
{
private readonly string _connectionString;
//public PropWorxDbContext(string connectionString)
//{
// _connectionString = connectionString;
//}
public PropWorxDbContext(DbContextOptions<PropWorxDbContext> options) : base(options)
{
}
public DbSet<Models.File> Files { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Models.File>().ToTable("Files");
}
//protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
//{
// optionsBuilder.UseMySQL(_connectionString);
// base.OnConfiguring(optionsBuilder);
//}
}
}
您不需要连接字符串或 OnConfiguring 覆盖,因为您正在 Startup.cs
中执行这些操作public void ConfigureServices(IServiceCollection services)
{
// This must come before MVC
services.AddDbContext<Models.PropWorxDbContext>(options => options.UseMySQL(Configuration.GetConnectionString("PropWorxConnection")));
services.AddMvc();
}
services.AddDbContext 行使用依赖注入注册您的数据库。这使您的控制器能够使用正确的构造函数工作
public FilesController(PropWorxDbContext context)
{
_context = context;
}
我认为您遇到的唯一问题是 DbContext 中不必要的代码,这会阻止依赖项注入容器更新它。
弄清楚了 - 我在 appsettings.json 中的 ConnectionStrings 格式不正确(我有一些奇怪的正斜杠 - 不知道为什么......感谢 Ahmar 和 user1900799 的帮助 - 非常感谢!