.NET 6 EF Code First:关联Incident与Transaction的实现咨询
.NET 6 EF Code First 实现Incident与Transaction关联方案
1. 实体类添加关联关系
给两个实体类建立外键与导航属性,明确关联逻辑:
Transaction(人员)类
public class Transaction { public int Id { get; set; } // 自身业务属性示例 public string PersonName { get; set; } public string PersonCode { get; set; } // 关联Incident的外键 public int IncidentId { get; set; } // 导航属性,关联对应的事件 public Incident Incident { get; set; } }
Incident(事件)类
public class Incident { public int Id { get; set; } public string Title { get; set; } public string Content { get; set; } public bool IsActive { get; set; } // 可选反向导航:便于从事件查询关联的人员记录 public ICollection<Transaction> Transactions { get; set; } = new List<Transaction>(); }
2. 配置DbContext并更新数据库
在DbContext中通过Fluent API明确关联规则,确保外键约束生效:
public class AppDbContext : DbContext { public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } public DbSet<Incident> Incidents { get; set; } public DbSet<Transaction> Transactions { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { // 配置Transaction与Incident的一对多关联 modelBuilder.Entity<Transaction>() .HasOne(t => t.Incident) .WithMany(i => i.Transactions) .HasForeignKey(t => t.IncidentId) .OnDelete(DeleteBehavior.Restrict); // 根据业务需求选择删除规则,如Cascade/Restrict } }
执行迁移命令更新数据库:
Add-Migration AddTransactionIncidentRelation Update-Database
3. 调整Transaction控制器逻辑
新增Transaction页面(Create)
在Get方法中查询所有IsActive=true的Incident,传给视图作为下拉选项:
public class TransactionController : Controller { private readonly AppDbContext _context; public TransactionController(AppDbContext context) { _context = context; } public IActionResult Create() { // 获取激活状态的事件列表(仅返回Id和显示用的Title) var activeIncidents = _context.Incidents .Where(i => i.IsActive) .Select(i => new { i.Id, i.Title }) .ToList(); ViewBag.IncidentOptions = new SelectList(activeIncidents, "Id", "Title"); return View(); } [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Create(Transaction transaction) { if (ModelState.IsValid) { _context.Add(transaction); await _context.SaveChangesAsync(); return RedirectToAction(nameof(Index)); } // 验证失败时重新加载下拉选项 var activeIncidents = _context.Incidents .Where(i => i.IsActive) .Select(i => new { i.Id, i.Title }) .ToList(); ViewBag.IncidentOptions = new SelectList(activeIncidents, "Id", "Title"); return View(transaction); }
Transaction列表页面(Index)
查询时用Include加载关联的Incident数据,避免N+1查询问题:
public async Task<IActionResult> Index() { // 加载Transaction及其关联的Incident var transactions = await _context.Transactions .Include(t => t.Incident) .ToListAsync(); return View(transactions); }
4. 调整视图代码
Create视图
添加下拉框选择激活的Incident:
<div class="form-group"> <label asp-for="IncidentId" class="control-label"></label> <select asp-for="IncidentId" asp-items="@ViewBag.IncidentOptions" class="form-control"> <option value="">请选择事件</option> </select> <span asp-validation-for="IncidentId" class="text-danger"></span> </div>
Index视图
在表格中同时展示Transaction自身属性与关联的Incident信息:
<table class="table"> <thead> <tr> <th>人员姓名</th> <th>人员编号</th> <th>关联事件标题</th> <th>事件状态</th> <th>操作</th> </tr> </thead> <tbody> @foreach (var item in Model) { <tr> <td>@item.PersonName</td> <td>@item.PersonCode</td> <td>@item.Incident.Title</td> <td>@(item.Incident.IsActive ? "激活" : "已关闭")</td> <td> <a asp-action="Edit" asp-route-id="@item.Id">编辑</a> | <a asp-action="Details" asp-route-id="@item.Id">详情</a> | <a asp-action="Delete" asp-route-id="@item.Id">删除</a> </td> </tr> } </tbody> </table>
可选优化:使用ViewModel
若不想直接在视图中使用实体类,可创建专门的ViewModel贴合视图需求:
public class TransactionCreateViewModel { public string PersonName { get; set; } public string PersonCode { get; set; } public int IncidentId { get; set; } public SelectList IncidentOptions { get; set; } }
修改Create Get方法逻辑:
public IActionResult Create() { var activeIncidents = _context.Incidents .Where(i => i.IsActive) .Select(i => new { i.Id, i.Title }) .ToList(); var viewModel = new TransactionCreateViewModel { IncidentOptions = new SelectList(activeIncidents, "Id", "Title") }; return View(viewModel); }
视图头部修改模型类型:@model TransactionCreateViewModel,下拉框绑定逻辑不变。
内容的提问来源于stack exchange,提问作者Eyetee
相关产品推荐
相关产品推荐

