如何将SQL Server中"All Fruits"表数据迁移至"All_Fruits"表?
解决方案:数据迁移与ASP.NET MVC CRUD实现
(示例表说明:展示了包含Fruit_Veg、Fruit_A、Fruit_B、Fruit_C、Fruit_D列的操作表,需填充Fruit系列列的ID值)
嘿,我来帮你搞定这个问题!结合你的场景——从Access导入SQL Server后的数据迁移,再到ASP.NET MVC Code First模式下的CRUD实现,咱们一步步来:
一、先解决All Fruits到All_Fruits的数据迁移问题
你的核心障碍之一是目标表的非空约束:原表Fruit A/B/C/D是nvarchar(225), null,但目标表是nvarchar(225), not null。所以首先要确保插入的数据满足非空要求,直接用SQL Server的INSERT语句就能完成初始迁移:
-- 假设你只需要迁移ID值,且原表的这些列已有有效ID(无NULL) INSERT INTO All_Fruits (Fruit_A, Fruit_B, Fruit_C, Fruit_D, Fruit_Veg) SELECT [Fruit A], [Fruit B], [Fruit C], [Fruit D], Fruit_Veg FROM [All Fruits] -- 如果原表存在NULL值,用空字符串填充以满足NOT NULL约束 -- SELECT ISNULL([Fruit A], ''), ISNULL([Fruit B], ''), ISNULL([Fruit C], ''), ISNULL([Fruit D], ''), Fruit_Veg FROM [All Fruits]
你可以先在SSMS里执行这段SQL验证,确保数据能顺利插入,再考虑是否集成到应用脚本里。
二、适配ASP.NET MVC Code First与现有数据库
因为你是Code First结合现有数据库,必须保证实体类和数据库表结构完全匹配:
1. 定义实体类
using System.ComponentModel.DataAnnotations; public class AllFruit { // 假设表有主键Id,根据你的实际情况调整 public int Id { get; set; } // 对应NOT NULL约束,添加[Required]特性 [Required] [StringLength(225)] public string Fruit_A { get; set; } [Required] [StringLength(225)] public string Fruit_B { get; set; } [Required] [StringLength(225)] public string Fruit_C { get; set; } [Required] [StringLength(225)] public string Fruit_D { get; set; } // 允许用户手动输入,无需非空约束 public string Fruit_Veg { get; set; } }
2. 配置DbContext
using Microsoft.EntityFrameworkCore; public class FruitDbContext : DbContext { public FruitDbContext(DbContextOptions<FruitDbContext> options) : base(options) { } // 映射到数据库中的All_Fruits表 public DbSet<AllFruit> All_Fruits { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { // 确保实体和表名映射正确 modelBuilder.Entity<AllFruit>().ToTable("All_Fruits"); // 如果实体属性名和表列名不一致,在这里配置映射,比如: // modelBuilder.Entity<AllFruit>().Property(f => f.Fruit_A).HasColumnName("Fruit_A"); } }
记得在appsettings.json里配置正确的数据库连接字符串哦!
三、实现查看、编辑、删除功能
你已经搞定了下拉列表的增删改,现在补充All_Fruits的CRUD操作:
1. 查看数据(Index页面)
在Controller里添加:
public class FruitController : Controller { private readonly FruitDbContext _context; public FruitController(FruitDbContext context) { _context = context; } // 展示所有数据 public IActionResult Index() { var allFruits = _context.All_Fruits.ToList(); return View(allFruits); } }
然后在Index视图里遍历展示数据:
@model List<AllFruit> <h1>所有水果数据</h1> <a asp-action="Create">添加新数据</a> <table> <thead> <tr> <th>Fruit Veg</th> <th>Fruit A ID</th> <th>Fruit B ID</th> <th>Fruit C ID</th> <th>Fruit D ID</th> <th>操作</th> </tr> </thead> <tbody> @foreach (var fruit in Model) { <tr> <td>@fruit.Fruit_Veg</td> <td>@fruit.Fruit_A</td> <td>@fruit.Fruit_B</td> <td>@fruit.Fruit_C</td> <td>@fruit.Fruit_D</td> <td> <a asp-action="Edit" asp-route-id="@fruit.Id">编辑</a> | <a asp-action="Delete" asp-route-id="@fruit.Id">删除</a> </td> </tr> } </tbody> </table>
2. 编辑数据
添加编辑的Action:
// 跳转编辑页面 public IActionResult Edit(int id) { var fruit = _context.All_Fruits.Find(id); if (fruit == null) { return NotFound(); } // 传递下拉列表数据源,比如Fruit A的可选ID ViewBag.FruitAOptions = GetFruitOptions<FruitA>(); ViewBag.FruitBOptions = GetFruitOptions<FruitB>(); ViewBag.FruitCOptions = GetFruitOptions<FruitC>(); ViewBag.FruitDOptions = GetFruitOptions<FruitD>(); return View(fruit); } // 提交编辑数据 [HttpPost] [ValidateAntiForgeryToken] public IActionResult Edit(int id, AllFruit fruit) { if (id != fruit.Id) { return NotFound(); } if (ModelState.IsValid) { try { _context.Update(fruit); _context.SaveChanges(); } catch (DbUpdateConcurrencyException) { if (!FruitExists(id)) { return NotFound(); } throw; } return RedirectToAction(nameof(Index)); } ViewBag.FruitAOptions = GetFruitOptions<FruitA>(); ViewBag.FruitBOptions = GetFruitOptions<FruitB>(); ViewBag.FruitCOptions = GetFruitOptions<FruitC>(); ViewBag.FruitDOptions = GetFruitOptions<FruitD>(); return View(fruit); } // 检查数据是否存在 private bool FruitExists(int id) { return _context.All_Fruits.Any(f => f.Id == id); } // 获取下拉列表数据源的通用方法 private SelectList GetFruitOptions<T>() where T : class { // 假设每个Fruit表有Id和Name列,根据实际结构调整 var options = _context.Set<T>().Select(f => new SelectListItem { Value = typeof(T).GetProperty("Id").GetValue(f).ToString(), Text = typeof(T).GetProperty("Name").GetValue(f).ToString() }).ToList(); return new SelectList(options, "Value", "Text"); }
3. 删除数据
添加删除的Action:
// 跳转删除确认页面 public IActionResult Delete(int id) { var fruit = _context.All_Fruits.Find(id); if (fruit == null) { return NotFound(); } return View(fruit); } // 确认删除数据 [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public IActionResult DeleteConfirmed(int id) { var fruit = _context.All_Fruits.Find(id); _context.All_Fruits.Remove(fruit); _context.SaveChanges(); return RedirectToAction(nameof(Index)); }
最后提醒
- 先在SSMS里验证SQL迁移语句的正确性,避免因为数据不符合约束导致应用报错
- 确保下拉列表的数据源方法
GetFruitOptions能正确从对应的Fruit A/B/C/D表获取数据 - 如果Code First出现迁移问题,可以使用
Add-Migration InitialCreate -IgnoreChanges来生成初始迁移,适配现有数据库
内容的提问来源于stack exchange,提问作者PhatLee
相关产品推荐
相关产品推荐

