简体   繁体   中英

Need help on table design with Entity Framework Core

I am developing a simple web application where a doctor is adding multiple prescription records for patients and will select multiple drugs while doing prescription. So one patient has multiple prescription and one prescription has multiple selected drugs. I have taken one another table patientrecords for reporting purpose/Normalization perspective where I am referencing patientID and PrescriptionID.

  • One patient --> many prescriptions --> one to many relationship
  • One prescriptions -> many drugs --> one to many relationship

Below is the model for patient, prescription and drugs, PatientRecord table.

患者模型

药物模型

处方模型

患者记录模型

While running migration, I get this error:

Error Number:1769,State:1,Class:16
Foreign key 'FK_Drugs_Prescriptions_PrescriptionID' references invalid column 'PrescriptionID' in referencing table 'Drugs'.

I am confused with explanation of one to many relationships on Microsoft website.

Can anyone help me with it?

There are a few things that don't quite look right here. Maybe if you clean them up you'll be close to spotting where the error is.

Firstly, I'm a bit confused by your PatientRecord class. It identifies itself with a PatientRecordId and it maps to a Patient , but it doesn't add any other information, so what is it for? If you're not going to add anything to that class, I think you can remove it from the model.

Secondly, your Prescription class maps to a collection of Drugs . That's perfect because you have a one-to-many relationship between them... so why does it also have an integer DrugId property? Unless you want the Prescription class to reference the Id of one single Drug as well as the collection of Drugs , I think you should remove it. It might be confusing Entity Framework and not giving you any value.

Thirdly, your Drug class maps to one Prescription (through its properties Prescription and PrescriptionId ) but why? Presumably a drug can appear on multiple prescriptions, as it could be prescribed to many people, or prescribed to the same person several times. So I think you want to remove that too and replace it with a many-to-many relationship.

Finally, if you want to have a many-to-many relationship between Prescription and Drug (and I think you will) you probably need to add a DrugPrescription class, with a Drug property and a Prescription property, to create this many-to-many mapping.

I think if you do that you'll be a lot close to your goal, and your error message will probably go away.

There are two ways to configure the relationships in EF Core

  • Conventions:By default, a relationship will be created when there is a navigation property discovered on a type. Not applicable to many-to-many relationship

  • Fluent API:you start by identifying the navigation properties that make up the relationship. HasOne or HasMany identifies the navigation property on the entity type you are beginning the configuration on. HasOne/WithOne are used for reference navigation properties and HasMany/WithMany are used for collection navigation properties.

From your screenshots and the benjamin suggested, you could configure the model like below

Patient - Prescription --> one to many relationship Prescription - Drug --> many to many relationship

public class Prescription
{
    public int PrescriptionId { get; set; }
    [Required]
    public string Description { get; set; }
    [Required]
    public DateTime PrescriptionDate { get; set; }

    public int PatientId { get; set; }

    public Patient Patient { get; set; }

    public ICollection<DrugPrescription> DrugPrescriptions { get; set; }
}
public class Drug
{
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }
    [Required]
    public int CurrentStock { get; set; }
    public int DrugCost { get; set; }
    public string Description { get; set; }

    public ICollection<DrugPrescription> DrugPrescriptions { get; set; }
}

//represent a many-to-many relationship by including an entity class for 
//the join table and mapping two separate one-to-many relationships.
 public class DrugPrescription
{
    public int DrugId { get; set; }
    public Drug Drug { get; set; }

    public int PrescriptionId { get; set; }
    public Prescription Prescription { get; set; }
}


//DbContext
public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {}

    public DbSet<Patient> Patient { get;set; }
    public DbSet<Drug> Drug { get;set; }
    public DbSet<Prescription> Prescription { get;set; }

    public DbSet<PatientRecord> PatientRecord { get; set; }


    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        #region Drug-Prescription Many-to-Many
        builder.Entity<DrugPrescription>()
            .HasKey(dp => new { dp.DrugId, dp.PrescriptionId });

        builder.Entity<DrugPrescription>()
            .HasOne(dp => dp.Prescription)
            .WithMany(p => p.DrugPrescriptions)
            .HasForeignKey(dp => dp.PrescriptionId)
            .OnDelete(DeleteBehavior.Restrict);

        builder.Entity<DrugPrescription>()
            .HasOne(dp => dp.Drug)
            .WithMany(d => d.DrugPrescriptions)
            .HasForeignKey(dp => dp.DrugId)
            .OnDelete(DeleteBehavior.Restrict);
        #endregion

    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM