.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 的帮助 - 非常感谢!