首页 > 解决方案 > asp.net 核心创建/更新外键

问题描述

我在我的“Todo”课程中添加了我的“Pharmacy”课程的外键。当我添加或编辑待办事项时,无法链接任何药房(从选择框)。这是我的模型:

public class Todo
    {
        [Key]
        public int ID { get; set; }

        public Pharmacy Pharmacy { get; set; }
    }

public class Pharmacy
    {
        [Key]
        public int PharmacyID { get; set; }

        public string Name { get; set; }

        public string Pharmacist { get; set; }

        [DataType(DataType.PhoneNumber)]
        public int Phone { get; set; }

        [DataType(DataType.EmailAddress)]
        public string Email { get; set; }

        public int NPA { get; set; }
        public string Street { get; set; }
        public string City { get; set; }
        public string Canton { get; set; }
    }

我的代码列表列出了我的 Todo 上的所有药房:

public class PharmacynamePageModel : PageModel
    {
        public SelectList PharmacyNameSL { get; set; }

        public void PopulatePharmacysDropDownList(ApplicationDbContext _context, object selectedPharmacy = null)
        {
            var query = (from p in _context.Pharmacy orderby p.Name select p).ToList();

            PharmacyNameSL = new SelectList(query, "PharmacyID", "Name", selectedPharmacy);
        }
    }

好吧,在这一步,我的 HTML 表单上有这段代码:

<label asp-for="Todo.Pharmacy" class="control-label"></label>
                <select asp-for="Todo.Pharmacy" class="form-control"
                        asp-items="Model.PharmacyNameSL">
                    <option value="">-- Select a Pharmacy --</option>
                </select>
                <span asp-validation-for="Todo.Pharmacy" class="text-danger" />

和我的 PostAsync() 进入我的创建和编辑控制器:

public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return Page();
            }

            var emptyTask = new Todo();

            if (await TryUpdateModelAsync(emptyTask, "Todo",  
                s => s.ID, s => s.OwnerID, 
                s => s.Title, s => s.Description,
                s => s.DueDate,
                s => s.Pharmacy,
                s => s.Priority))
            {
                emptyTask.Status = EnumStatus.Open;
                _context.Todo.Add(emptyTask);
                await _context.SaveChangesAsync();
                if (emptyTask.OwnerID != HttpContext.User.Identity.Name)
                {
                    LogVM.AddLog("Todos", $"{HttpContext.User.Identity.Name} attributed a new task to {emptyTask.OwnerID}.", _context);
                }
                return RedirectToPage("./Index");
            }

            PopulatePharmacysDropDownList(_context, emptyTask.Pharmacy);

            return RedirectToPage("./Index");
        }

所有数据都被映射/绑定,但不是药房字段,其值始终为空。

希望你能帮我 :)。

感谢提前。

标签: asp.net-coreforeign-keysentity-framework-coremodel-binding

解决方案


在发布时,数据绑定会将 Select 的“dataValueField”绑定到模型的数据成员

您正在尝试将整个对象映射到 Select 的选定项目。您提到只有 Pharmacy 字段为空 - 这可能是因为从您提供的代码看来,这是您可能尝试修改的唯一字段。其他项目的值可能是在页面代码本身中设置的(并且不是在 Post 上绑定的数据)。

我建议您为选定的“药房”项目创建一个单独的字段并将其绑定到“选择”框。

在您的 PharmacynamePageModel 类中,创建一个公共“可绑定”属性,如下所示:

 [BindProperty]
 public string SelectedPharmacy { get; set; }

然后在 Razor 代码上,不是绑定到“Pharmacy”,而是绑定到“SelectedPharmacy”(在 asp-for 属性中),如下所示:

                <select asp-for="SelectedPharmacy" class="form-control"
                        asp-items="Model.PharmacyNameSL">
                    <option value="">-- Select a Pharmacy --</option>
                </select>
                <span asp-validation-for="Todo.Pharmacy" class="text-danger" />

现在,在 Form post 上,所选的 Pharmacy Id 应该可用。您可以根据需要使用 ID。

希望这有效。如果是,请将此标记为答案。


推荐阅读