msawczyn / EFDesigner2022

Entity Framework visual design surface and code-first code generation for EF6, Core and beyond
MIT License
119 stars 21 forks source link

Missing ForaignKey on 1 <-> 0..1 #25

Closed Mr-Pearce closed 1 year ago

Mr-Pearce commented 1 year ago

Unchanged grafik

Created DbContext Code: v4.0.1.0

modelBuilder.Entity<Upload>()
         .HasOne<Commit>(p => p.Commit)
         .WithOne(p => p.Upload)
         .HasForeignKey("Commit", "UploadId")
         .OnDelete(DeleteBehavior.Cascade);

v4.1.2.0

modelBuilder.Entity<Upload>()
             .HasOne<Commit>(p => p.Commit)
             .WithOne(p => p.Upload);

Error v4.1.2.0

System.InvalidOperationException: The dependent side could not be determined for the one-to-one relationship between 'Commit.Upload' and 'Upload.Commit'. 
To identify the dependent side of the relationship, configure the foreign key property. If these navigations should not be part of the same relationship, configure them independently via separate method chains in 'OnModelCreating'. See http://go.microsoft.com/fwlink/?LinkId=724062 for more details.

When i ad the missing two lines back it works like before.

Working but still strange grafik

v4.0.1.0

modelBuilder.Entity<Program>()
         .HasMany<Upload>(p => p.Uploads)
         .WithOne(p => p.Program)
         .HasForeignKey("ProgramId")
         .OnDelete(DeleteBehavior.NoAction)
         .IsRequired();

v4.1.2.0

modelBuilder.Entity<Program>()
         .HasMany<Upload>(p => p.Uploads)
         .WithOne(p => p.Program);

Is this behavior expected?

msawczyn commented 1 year ago

Using the latest version (4.2.0) I made the following model: image

It generated the code

         modelBuilder.Entity<global::EFVisualEditorTest.Child>()
                     .ToTable("Child")
                     .HasKey(t => t.ID);
         modelBuilder.Entity<global::EFVisualEditorTest.Child>()
                     .Property(t => t.ID)
                     .ValueGeneratedOnAdd()
                     .IsRequired();
         modelBuilder.Entity<global::EFVisualEditorTest.Child>()
                     .Property(t => t.PID)
                     .IsRequired();
         modelBuilder.Entity<global::EFVisualEditorTest.Child>().HasIndex(t => t.PID);

         modelBuilder.Entity<global::EFVisualEditorTest.Parent>()
                     .ToTable("Parent")
                     .HasKey(t => t.ID);
         modelBuilder.Entity<global::EFVisualEditorTest.Parent>()
                     .Property(t => t.ID)
                     .ValueGeneratedOnAdd()
                     .IsRequired();
         modelBuilder.Entity<global::EFVisualEditorTest.Parent>()
                     .HasOne<global::EFVisualEditorTest.Child>(p => p.Child)
                     .WithOne(p => p.Parent)
                     .HasForeignKey<global::EFVisualEditorTest.Child>(k => k.PID);

which migrated fine and created the database.

Possibly the issue slipped by in a prior version but is fixed now. Can you give it another try?

Mr-Pearce commented 1 year ago

The Entities above are fine now. But i found another "inconsistency" Bidirectinal Associations generate different code depending on the Start and End point even when you set the Multiplicity the same. Although it looks identical in the Model Diagram.

Left: Bidirectional from Upload -> Release Right: Bidirectional from Release -> Upload with switched Multiplicity It looks nearly the same in the Model Diagram, shouldn't this create identical modelBuilderCode?

grafik

msawczyn commented 1 year ago

That's a side effect of how the T4 iterates through the classes. The resulting code is functionally identical, ignoring the change resulting from the removal in the model of the UploadId foreign key property. There isn't a need to change what it does since it produces the same model in Entity Framework Core.

Of course, since this processing happens in the T4, you're free to change it if it's bothersome. But it doesn't worry me from a product functionality standpoint.

Thanks for pointing it out. Since the original issue is resolved, I'll close this ticket.