通过单个创建页面为多个模型 class 插入数据

insert data for multiple model class via single create page

我有两个模型class

public class DiagnosisModel
    {
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int DiagnosisId { get; set; } 
        public string DiagnosisName { get; set; }
    }
    
public class PatientModel
    {
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int PatientId { get; set; } 
        public string PatientName { get; set; }
        public string Contact { get; set; }
        
        public int DiagnosisId { get; set; }
        public DiagnosisModel Diagnosis { get; set; }   
    }

我必须制作一个创建页面,我们可以在其中插入 Patient Information 以及 diagnosis 类型。

但是可能会有新的诊断名称,我们必须将其插入数据库。为此,我必须创建一个文本框以在同一页面中插入新的 DiagnosisName。不像去 DiagnosisModel->Create page 并插入新的诊断名称。 我用谷歌搜索检查在单个页面中插入多个模型,但只有查看页面示例。我没有找到任何为多个模型 classes 插入数据的示例。 如何从单个创建页面为多个模型 classes 插入数据?

在使用“模型”的范围内思考“模型”会有所帮助。创建的视图逻辑需要传递信息以最终创建数据。这可能导致与数据模型的一对一关系,或者负责创建多个数据模型。视图的模型不一定是数据模型,可以说在大多数情况下它应该是视图模型,它是一个简单的、可序列化的 POCO,仅中继视图和相关操作所需的信息。这使得服务器和客户端之间的通信紧凑而高效,并减少了从数据库中提取的数据量。当经常使用实体以使操作正常工作时,您最终必须为未显示的实体上的值定义隐藏字段,以便发送回操作的序列化表单数据或“实体”相当完整足够。随着应用程序的发展和增加客户端与服务器之间的消息大小,这最终会导致错误,并且会暴露比客户端可能知道的更多关于您的域的信息。

对于非常简单的小型操作,您甚至可能不需要视图模型,只需将值作为参数传递给操作即可。例如在删除操作的情况下,我们不需要发送整个实体来告诉服务器删除它,我们可以只传递 PK 字段。

所以对于像创建患者这样的事情,我们可以定义一个 CreatePatientViewModel:

[Serializable]
public class CreatePatientViewModel
{
    public string Name { get; set; } 
    public string Contact { get; set; }
    public string Diagnosis { get; set; }
}

然后在视图中我们在控制器上调用 CreatePatient 操作的地方,我们将匹配值打包在 JSON 中。即作为 Ajax 调用的一部分:

data: {Name = name, Contact = contact, Diagnosis = diagnosis }

这些值是从相关的输入控件等中提取的

从该视图模型中,我们可以在操作中组合新的 Patient 和相关的 Diagnosis 实体。

public JsonResult CreatePatient(CreatePatientViewModel patientVM)
{
    if (patientVM == null)
        throw new ArgumentNullException("patientVM");

    using (var context = new AppDbContext())
    {
        var patient = new PatientModel 
        {
            Name = patientVM.Name,
            Contact = patientVM.Contact,
            Diagnosis = new DiagnosisModel
            {
                DiagnosisName = patientVM.Diagnosis
            }
        };
        context.Patients.Add(patient);
        context.SaveChanges();
        return Json(new { success = true; patientId = patient.PatientId });
    }
}

代码逻辑可以采取措施检查重复数据或对提供的值执行验证。显然,我们会添加异常处理来处理任何错误并通知用户任何问题。在此示例中,操作 returns 一个 JSON 对象来指示调用是否成功并传回新的患者 ID。或者,您可以传回 ViewResult 以刷新页面等。只有 3 个参数,您可以将这 3 个值作为参数传递。系统往往会发展,因此定义视图模型通常比附加参数更清晰。

在我们可能想要创建一个与现有其他实体有关联的新实体的情况下,例如注意到他们从下拉列表中选择的诊所的家庭医生,我们会发送类似从他们的选择中提取的 DoctorId 而不是担心传递整个 Doctor 实体。 CreatePatient 操作可以验证提供的医生 ID 是否有效,并解析 DbContext 中的 Doctor 实体以关联到新的 Patient 实体。

    using (var context = new AppDbContext())
    {
        var doctor = context.Doctors.Single(x => x.DoctorId == patientVM.FamilyDoctorId);
        var patient = new PatientModel 
        {
            Name = patientVM.Name,
            Contact = patientVM.Contact,
            Doctor = doctor,
            Diagnosis = new DiagnosisModel
            {
                DiagnosisName = patientVM.Diagnosis
            }
        };
        context.Patients.Add(patient);
        context.SaveChanges();

这假定家庭医生的选择是强制性的,并提供了所提供的医生 ID 有效的内在验证。