How to relate two unrelated foreign keys back to t

2019-09-12 17:04发布

问题:

Using EF code first, I created compound primary key on Packages and Services consisting of Id and Member_Id.

Then I made foreign keys from both of those tables into Promises.

As you can see it didn't relate the two foreign keys back to the same Member thus allowing the package member to be different than the service member. This is not what I intended.

I intend to have Promises just have a single Member_Id column and reuse it in both foreign keys. In problem terms, I intend for promises to only have services of the member that owns that promise's package.

I can easily do this in the database. See this fixed diagram:

This features compound foreign keys from Promises back to Packages and Services.

How can I attribute my classes in EF to achieve this result?

Is my only option to Database First migration and check and see what it does to mimic what I did manually in the database diagram editor?

回答1:

I had to:

  1. Fix my database the way I wanted it
  2. Create a new Class Libray Project
  3. Add Entity Framework Model. Choose Code First from Existing Database
  4. Look at the differences between my classes and the generated classes from Database First, and see which ones I need to apply to my model. In this case, I found that the only way to create the foreign keys I wanted was with code not attributes and this is done in the OnModelCreating routine in the model (DbContext) class:
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
      modelBuilder.Entity<Member>()
          .HasMany(e => e.Packages)
          .WithRequired(e => e.Member)
          .HasForeignKey(e => e.Member_Id);

      modelBuilder.Entity<Member>()
          .HasMany(e => e.Products)
          .WithRequired(e => e.Member)
          .HasForeignKey(e => e.Member_Id);

      modelBuilder.Entity<Member>()
          .HasMany(e => e.Services)
          .WithRequired(e => e.Member)
          .HasForeignKey(e => e.Member_Id);

      modelBuilder.Entity<Package>()
        .HasMany(e => e.Promises)
        .WithRequired(e => e.Package)
        .HasForeignKey(e => new { e.Package_Id, e.Member_Id })
        .WillCascadeOnDelete(false);

      modelBuilder.Entity<Service>()
        .HasMany(e => e.Promises)
        .WithRequired(e => e.Service)
        .HasForeignKey(e => new { e.Service_Id, e.Member_Id })
        .WillCascadeOnDelete(false);
    }