You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 12:50:16