0

I have two model 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; }   
    }

I have to make a create page where we can insert Patient Information along with the diagnosis type.

But there may be come new Diagnosis Name which we have to insert into database. For that, I have to create a textbox to insert new DiagnosisName in the same page. Not like going to DiagnosisModel->Create page and insert new Diagnosis Name. I googled to check insert multiple models in single page, but there are only view page examples. I did not find any example to insert data for multiple model classes. How can I insert data for multiple model classes from single create page?

1 Answer 1

1

It helps to think of "Models" in the scope of where they are used. View logic for a create needs to pass information to ultimately create data. This may result in a one-to-one relationship with a data model, or be responsible for creating multiple data models. The model for a view does not have to be a data model, arguably in most cases it should be a View Model, being a simple, serialize-able POCO relaying only as much information that the view and related action(s) need. This makes communication between servers and clients compact and efficient, and reduces the amount of data being drawn down from the database. When working with entities often for the actions to work properly you end up having to define hidden fields for values on the entity(ies) that aren't displayed so that the serialized form data or "entity" sent back to the action is reasonably complete enough. This ends up leading to bugs as applications evolve and increases the message size between client and server, plus exposes more info about your domain than the client should probably know about.

For very simple, small operations you might not even need a view model, just pass values as arguments to an action. For example in the case of a Delete operation, we don't need to send the entire entity to tell the server to delete it, we can pass just the PK field.

So for something like creating a patient we might define a CreatePatientViewModel:

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

Then where in the view we call a CreatePatient action on the controller, we package the matching values in JSON. i.e. as part of an Ajax call:

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

Where those values are extracted from the relevant entry controls, etc.

From that view model we can compose our new Patient and related Diagnosis entities within the action.

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 });
    }
}

The code logic can take measures to check for duplicate data or perform validations on the values provided. Obviously we'd add exception handling to handle any errors and notify the user of any issues. In this example the action returns a JSON object to indicate if the call was successful and passes back the new patient ID. Alternatively you might pass back a ViewResult to refresh the page, etc. With only 3 arguments you could just pass those 3 values as parameters. Systems tend to evolve so it's usually cleaner to define a view model rather than appending parameters.

In situations where we might want to create a new entity that has associations with existing other entities, like for instance noting a Family doctor from the clinic that they pick from a drop-down list, we would send along something like the DoctorId extracted from their selection rather than worrying about passing an entire Doctor entity around. The CreatePatient action can verify the provided doctor ID is valid and resolve a Doctor entity from the DbContext to associate to the new Patient entity.

    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();

This assumes the family doctor selection is mandatory, and provides the inherent validation that the Doctor ID provided is a valid one.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.