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

ASP.NET MVC模型依赖实现:为Loan添加公司选择下拉列表

ASP.NET MVC 借贷记录表单实现方案

1. 修正模型关联定义

首先明确Company与Loan的一对多关联规则,通过EF实现正确的外键和导航属性:

// Company模型
public class Company
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }

    // 导航属性:该公司作为出借方的所有借贷记录
    public ICollection<Loan> GivenLoans { get; set; } = new List<Loan>();
    // 导航属性:该公司作为借入方的所有借贷记录
    public ICollection<Loan> ReceivedLoans { get; set; } = new List<Loan>();
}

// Loan模型
public class Loan
{
    public int Id { get; set; }
    public decimal Amount { get; set; }
    public DateTime LoanDate { get; set; }

    // 出借方外键
    public int FromCompanyId { get; set; }
    public Company FromCompany { get; set; }

    // 借入方外键
    public int ToCompanyId { get; set; }
    public Company ToCompany { get; set; }
}

在DbContext中用Fluent API明确关联规则(可选,增强可读性):

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Loan>()
        .HasOne(l => l.FromCompany)
        .WithMany(c => c.GivenLoans)
        .HasForeignKey(l => l.FromCompanyId)
        .OnDelete(DeleteBehavior.Restrict); // 防止删除公司时连带删除借贷记录

    modelBuilder.Entity<Loan>()
        .HasOne(l => l.ToCompany)
        .WithMany(c => c.ReceivedLoans)
        .HasForeignKey(l => l.ToCompanyId)
        .OnDelete(DeleteBehavior.Restrict);
}

2. 创建视图模型(ViewModel)

为了同时传递借贷表单数据和公司下拉选项,定义专用视图模型:

public class CreateLoanViewModel
{
    [Required(ErrorMessage = "请输入借贷金额")]
    public decimal Amount { get; set; }

    [Required(ErrorMessage = "请选择借贷日期")]
    public DateTime LoanDate { get; set; }

    [Required(ErrorMessage = "请选择出借公司")]
    public int FromCompanyId { get; set; }

    [Required(ErrorMessage = "请选择借入公司")]
    public int ToCompanyId { get; set; }

    // 公司下拉选项集合
    public IEnumerable<SelectListItem> CompanyOptions { get; set; }
}

3. 完善控制器逻辑

在LoansController中实现GET和POST方法,处理数据加载和表单提交:

GET方法(加载表单)

private readonly ApplicationDbContext _context;

public LoansController(ApplicationDbContext context)
{
    _context = context;
}

public IActionResult Create()
{
    // 查询所有公司,转换为下拉选项
    var companyOptions = _context.Companies
        .Select(c => new SelectListItem
        {
            Value = c.Id.ToString(),
            Text = c.Name
        })
        .ToList();

    var viewModel = new CreateLoanViewModel
    {
        CompanyOptions = companyOptions,
        LoanDate = DateTime.Now // 默认填充当前日期
    };

    return View(viewModel);
}

POST方法(提交表单)

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(CreateLoanViewModel viewModel)
{
    if (!ModelState.IsValid)
    {
        // 验证失败时重新加载公司选项
        viewModel.CompanyOptions = _context.Companies
            .Select(c => new SelectListItem
            {
                Value = c.Id.ToString(),
                Text = c.Name
            })
            .ToList();
        return View(viewModel);
    }

    // 将视图模型转换为Loan实体
    var loan = new Loan
    {
        Amount = viewModel.Amount,
        LoanDate = viewModel.LoanDate,
        FromCompanyId = viewModel.FromCompanyId,
        ToCompanyId = viewModel.ToCompanyId
    };

    _context.Loans.Add(loan);
    await _context.SaveChangesAsync();

    return RedirectToAction(nameof(Index));
}

4. 实现视图下拉列表

在Create.cshtml中生成下拉选择框,并添加表单验证:

@model CreateLoanViewModel

@{
    ViewData["Title"] = "新建借贷记录";
}

<h1>新建借贷记录</h1>

<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            
            <div class="form-group">
                <label asp-for="Amount" class="control-label"></label>
                <input asp-for="Amount" class="form-control" />
                <span asp-validation-for="Amount" class="text-danger"></span>
            </div>
            
            <div class="form-group">
                <label asp-for="LoanDate" class="control-label"></label>
                <input asp-for="LoanDate" type="date" class="form-control" />
                <span asp-validation-for="LoanDate" class="text-danger"></span>
            </div>
            
            <div class="form-group">
                <label class="control-label">出借公司</label>
                @Html.DropDownListFor(m => m.FromCompanyId, Model.CompanyOptions, "请选择公司", new { @class = "form-control" })
                <span asp-validation-for="FromCompanyId" class="text-danger"></span>
            </div>
            
            <div class="form-group">
                <label class="control-label">借入公司</label>
                @Html.DropDownListFor(m => m.ToCompanyId, Model.CompanyOptions, "请选择公司", new { @class = "form-control" })
                <span asp-validation-for="ToCompanyId" class="text-danger"></span>
            </div>
            
            <div class="form-group">
                <input type="submit" value="创建" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">返回列表</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
    <script>
        // 禁止选择同一公司作为出借和借入方
        document.getElementById('FromCompanyId').addEventListener('change', function() {
            const toSelect = document.getElementById('ToCompanyId');
            const selectedFrom = this.value;
            
            for (let i = 0; i < toSelect.options.length; i++) {
                toSelect.options[i].disabled = toSelect.options[i].value === selectedFrom;
            }
        });
    </script>
}

5. 额外优化建议

  • 若公司数据量大,可添加搜索功能或分页加载下拉选项
  • 可在服务器端添加验证,禁止出借方和借入方为同一公司
  • 可通过EF迁移确保数据库表结构正确生成

内容的提问来源于stack exchange,提问作者Thibault_Km

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 01:45:03