Visual Studio添加迁移与控制器后数据库MenuItem表未生成如何解决
问题描述
我正在Visual Studio Community中开发应用,希望将已创建的Model同步生成为数据库中的表,目前遇到问题但经验不足无法定位原因,已花费数小时搜索相关关键词,未找到有效解决信息。
具体问题
我目前创建了Alert和MenuItem两个Model,为Alert模型搭建了脚手架控制器后,已成功同步到数据库中,运行完全符合预期。但后续处理数据库时未能得到相同结果:我创建了MenuItem模型,为其新增脚手架项,执行Add-Migration命令,再运行Update-Database命令,刷新SQL Server Object Explorer后,数据库中仅存在Alert表。
以下是可能有参考价值的相关文件,我无法理解为何数据库没有按照所学逻辑新增对应表。
MenuItem.cs
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; namespace _6thStreetDive.Models { public class MenuItem { public int Id { get; set; } public string Name { get; set; } public string Desc { get; set; } public bool ShowMainPrice { get; set; } [Column(TypeName = "decimal(18,4)")] public decimal MainPrice { get; set; } public string Category { get; set; } [NotMapped] public Dictionary<string, decimal> Options { get; set; } } }
MenuItemsController.cs
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using _6thStreetDive.Data; using _6thStreetDive.Models; namespace _6thStreetDive.Controllers { [Route("api/[controller]")] [ApiController] public class MenuItemsController : ControllerBase { private readonly _6thStreetDiveContext _context; public MenuItemsController(_6thStreetDiveContext context) { _context = context; } // GET: api/MenuItems [HttpGet] public async Task<ActionResult<IEnumerable<MenuItem>>> GetMenuItem() { return await _context.MenuItem.ToListAsync(); } // GET: api/MenuItems/5 [HttpGet("{id}")] public async Task<ActionResult<MenuItem>> GetMenuItem(int id) { var menuItem = await _context.MenuItem.FindAsync(id); if (menuItem == null) { return NotFound(); } return menuItem; } // PUT: api/MenuItems/5 // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754 [HttpPut("{id}")] public async Task<IActionResult> PutMenuItem(int id, MenuItem menuItem) { if (id != menuItem.Id) { return BadRequest(); } _context.Entry(menuItem).State = EntityState.Modified; try { await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!MenuItemExists(id)) { return NotFound(); } else { throw; } } return NoContent(); } // POST: api/MenuItems // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754 [HttpPost] public async Task<ActionResult<MenuItem>> PostMenuItem(MenuItem menuItem) { _context.MenuItem.Add(menuItem); await _context.SaveChangesAsync(); return CreatedAtAction("GetMenuItem", new { id = menuItem.Id }, menuItem); } // DELETE: api/MenuItems/5 [HttpDelete("{id}")] public async Task<IActionResult> DeleteMenuItem(int id) { var menuItem = await _context.MenuItem.FindAsync(id); if (menuItem == null) { return NotFound(); } _context.MenuItem.Remove(menuItem); await _context.SaveChangesAsync(); return NoContent(); } private bool MenuItemExists(int id) { return _context.MenuItem.Any(e => e.Id == id); } } }
Context.cs
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using _6thStreetDive.Models; namespace _6thStreetDive.Data { public class _6thStreetDiveContext : DbContext { public _6thStreetDiveContext (DbContextOptions<_6thStreetDiveContext> options) : base(options) { } public DbSet<_6thStreetDive.Models.Alert> Alert { get; set; } public DbSet<_6thStreetDive.Models.MenuItem> MenuItem { get; set; } } }
已尝试的解决方案
- 删除迁移记录,重新执行InitialCreate初始化
- 新增多个迁移记录
- 删除MenuItem控制器后重新执行脚手架搭建
- 关闭并重启Visual Studio
- 重建项目后重复上述步骤
执行操作步骤
- 创建Model
- 添加新脚手架项
- 执行
Add-Migration "自定义迁移名称" - 执行
Update-Database - 刷新SSOE视图
解决方案
按以下优先级排查即可定位问题:
- 检查迁移文件内容
执行Add-Migration后,打开项目Migrations文件夹下刚生成的迁移文件,查看Up方法中是否包含创建MenuItem表的代码:- 如果没有,执行
Remove-Migration删除空迁移,先修复MenuItem模型的可空引用问题:将所有string属性添加默认值或标记为可空,示例:public string Name { get; set; } = string.Empty;,修复后重新执行Add-Migration即可。 - 如果有,进入下一步排查。
- 如果没有,执行
- 校验连接字符串一致性
打开appsettings.json检查默认连接字符串对应的数据库实例、库名,确认与SQL Server Object Explorer中打开的数据库完全一致,90%的同类问题都是连接到了错误的数据库实例导致。 - 验证迁移执行状态
打开目标数据库的__EFMigrationsHistory系统表,查看本次迁移的记录是否已存在:- 如果不存在,执行
Update-Database -Verbose查看详细执行日志,定位执行失败的具体原因。 - 如果存在但无对应表,执行
Script-Migration生成完整SQL脚本,手动在目标数据库执行即可看到具体报错信息。
- 如果不存在,执行
- 终极解决方法
如果上述步骤都无效,直接删除本地数据库文件、清空项目Migrations文件夹,重新执行Add-Migration InitialCreate和Update-Database,即可生成包含两个表的全新数据库。
内容的提问来源于stack exchange,提问作者Tyler
相关产品推荐
相关产品推荐

