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

如何从其他模型获取数据并实现根据所选办公室自动填充墨盒信息

Great question—let's break this down into actionable steps to solve both your requirements, starting with a small model tweak that'll make your data more reliable long-term.

Step 1: Refactor Models for Better Data Integrity

Right now, your Order stores the office name as a string, which is fragile—if an office gets renamed, existing orders will show outdated names and lose their reliable link to the correct cartridge. Instead, we'll use the office's Id as a foreign key:

Office.cs (no changes needed, just for reference):

public class Office {
    public int Id { get; set; }
    public string Name { get; set; } = "";
    public string Cartridge { get; set; } = "";
}

Updated Order.cs:

public class Order {
    public int Id { get; set; }
    public DateTime Created { get; set; }
    public int OfficeId { get; set; } // Store office ID instead of name
    public string Cartridge { get; set; } = "";
    // Optional: Add navigation property if using EF Core for easier querying
    public Office? Office { get; set; }
}

Step 2: Auto-Fill Cartridge on Office Selection (Create/Edit Form)

We'll use JavaScript to listen for dropdown changes and populate the cartridge field. You have two solid options here:

Option A: Client-Side (Faster, No API Call)

Pass full office data to the view, then map IDs to cartridges for instant lookup:

Update OrdersController.cs (EditOrder GET method):

[HttpGet]
public IActionResult EditOrder(int? id) {
    var offices = _repo.GetAllOffices();
    // Use Office.Id as the dropdown value, Name as the display text
    ViewBag.Offices = new SelectList(offices, "Id", "Name");
    ViewBag.OfficeData = offices; // Send full office data to the view

    if (id == null) return View(new Order());
    else {
        var order = _repo.GetOrder((int)id);
        return View(order);
    }
}

Update the EditOrder View:
Add a disabled cartridge input (so users can't edit it) and the JavaScript to handle the dropdown:

@model Order
<div>
    <form asp-controller="Orders" asp-action="EditOrder" method="post">
        <input asp-for="Id" type="hidden" />
        <input asp-for="Created" type="hidden" />
        <div>
            <label>Your office</label>
            <select asp-for="OfficeId" asp-items="ViewBag.Offices"></select>
        </div>
        <div>
            <label>Cartridge</label>
            <input asp-for="Cartridge" type="text" disabled />
        </div>
        <input type="submit" value="Send" />
    </form>
</div>

<script>
    // Serialize office data from ViewBag into a JS object
    const officeData = @Html.Raw(Json.Serialize(ViewBag.OfficeData));
    const cartridgeMap = {};
    officeData.forEach(office => {
        cartridgeMap[office.id] = office.cartridge;
    });

    // Handle dropdown changes
    const officeSelect = document.querySelector('#OfficeId');
    const cartridgeInput = document.querySelector('#Cartridge');

    officeSelect.addEventListener('change', () => {
        cartridgeInput.value = cartridgeMap[officeSelect.value] || '';
    });

    // Initialize cartridge field when editing an existing order
    document.addEventListener('DOMContentLoaded', () => {
        if (officeSelect.value) {
            cartridgeInput.value = cartridgeMap[officeSelect.value] || '';
        }
    });
</script>

Option B: Server-Side API Call (For Dynamic Data)

If office data changes frequently, create an API endpoint to fetch the cartridge by office ID:

Add to OrdersController.cs:

[HttpGet("GetCartridgeByOfficeId")]
public IActionResult GetCartridgeByOfficeId(int officeId) {
    var office = _repo.GetOffice(officeId);
    if (office == null) return NotFound();
    return Ok(new { Cartridge = office.Cartridge });
}

Update the View's Script:

<script>
    const officeSelect = document.querySelector('#OfficeId');
    const cartridgeInput = document.querySelector('#Cartridge');

    officeSelect.addEventListener('change', async () => {
        const officeId = officeSelect.value;
        if (!officeId) {
            cartridgeInput.value = '';
            return;
        }

        const response = await fetch(`/Orders/GetCartridgeByOfficeId?officeId=${officeId}`);
        if (response.ok) {
            const data = await response.json();
            cartridgeInput.value = data.Cartridge;
        }
    });

    // Initialize for existing orders
    document.addEventListener('DOMContentLoaded', async () => {
        const officeId = officeSelect.value;
        if (officeId) {
            const response = await fetch(`/Orders/GetCartridgeByOfficeId?officeId=${officeId}`);
            if (response.ok) {
                const data = await response.json();
                cartridgeInput.value = data.Cartridge;
            }
        }
    });
</script>

Secure the Post Method:
To prevent client-side tampering, override the cartridge value from the database when saving:

[HttpPost]
public async Task<IActionResult> EditOrder(Order order) {
    if (order.Id > 0) {
        var existingOrder = _repo.GetOrder(order.Id);
        if (existingOrder != null) {
            existingOrder.OfficeId = order.OfficeId;
            existingOrder.Cartridge = _repo.GetOffice(order.OfficeId)?.Cartridge ?? "";
            _repo.UpdateOrder(existingOrder);
        }
    } else {
        order.Cartridge = _repo.GetOffice(order.OfficeId)?.Cartridge ?? "";
        _repo.AddOrder(order);
    }
    if (await _repo.SaveChangesAsync()) return RedirectToAction("Orders");
    else return View(order);
}

Step 3: Show Correct Cartridge in Order List

Now that we're storing OfficeId, we have two clean ways to display the cartridge:

Option 1: Use EF Core Navigation Properties

Update your repository's GetAllOrders method to include the Office navigation property:

public IEnumerable<Order> GetAllOrders() {
    return _context.Orders.Include(o => o.Office).ToList();
}

Update the Orders View:

@model IEnumerable<Order>
<table>
    <thead>
        <tr>
            <th>Created Date</th>
            <th>Office</th>
            <th>Cartridge</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var order in Model) {
            <tr>
                <td>@order.Created.ToString("yyyy-MM-dd HH:mm")</td>
                <td>@order.Office?.Name ?? "Unknown Office"</td>
                <td>@order.Office?.Cartridge ?? "No Cartridge Assigned"</td>
            </tr>
        }
    </tbody>
</table>

Option 2: Map Cartridges in the Controller (No Navigation Properties)

If you don't want to use navigation properties, fetch offices and map cartridges to orders in the controller:

public IActionResult Orders(int id) {
    var orders = _repo.GetAllOrders();
    var officeLookup = _repo.GetAllOffices().ToDictionary(o => o.Id, o => o);
    
    foreach (var order in orders) {
        if (officeLookup.TryGetValue(order.OfficeId, out var office)) {
            order.Cartridge = office.Cartridge;
        }
    }
    return View(orders);
}

Then your existing view code @order.Cartridge will work as expected.


Quick Tips

  • Always validate that the OfficeId exists in the database before saving orders to avoid invalid data.
  • Using office IDs instead of names makes your system more robust—names can change, but IDs should remain consistent.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 13:32:38