dotnet / efcore

EF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
https://docs.microsoft.com/ef/
MIT License
13.48k stars 3.13k forks source link

Entity Framework Core generates a Foreign Key to the wrong table when using Entity Splitting #29915

Open HSchwichtenberg opened 1 year ago

HSchwichtenberg commented 1 year ago

2 simple entities:

public class Company
{
 public int CompanyID { get; set; } 
 [StringLength(50)]
 public string Name { get; set; }
 [StringLength(50)]
 public string City { get; set; }
 [StringLength(50)]
 public string Street { get; set; }
 [StringLength(10)]
 public string Postcode { get; set; }
 [StringLength(50)]
 public string Country { get; set; }

 public List<Management> ManagementSet { get; set; } = new();
}

public class Management
{
 public int ID { get; set; } 
 public string Name { get; set; }
 public string Role { get; set; }
 public Company Company { get; set; }
 public int CompanyId { get; set; } 
}

Context Class with Entity Splitting for Company:

public class CompanyContext : DbContext
{
 public DbSet<Company> Company { get; set; }
 public DbSet<Management> Management { get; set; }

 protected override void OnConfiguring(DbContextOptionsBuilder builder)
 {
  string connstring = @$"Server=YourServer;Database=EFC_MappingScenarios_EntitySplitting;Trusted_Connection=True;MultipleActiveResultSets=True;encrypt =false";
  builder.UseSqlServer(connstring); //.LogTo(CUI.PrintAlternatingColor);
  builder.EnableSensitiveDataLogging(true);
 }

 protected override void OnModelCreating(ModelBuilder modelBuilder)
 {
  #region Entity Splitting
  modelBuilder.Entity<Company>(
  entityBuilder =>
  {
   entityBuilder
     .SplitToTable(
         "Address",
         tableBuilder =>
         {
       tableBuilder.Property(x => x.City);
       tableBuilder.Property(x => x.Street).HasColumnName("Streetname");
       tableBuilder.Property(x => x.Postcode);
       tableBuilder.Property(x => x.Country);
      });
  });

  #endregion
 }
}

This will create a Foreign Key in Management that points to table Address instead of table Company :-(

ALTER TABLE [dbo].[Management]  WITH CHECK ADD  CONSTRAINT [FK_Management_Address_CompanyId] FOREIGN KEY([CompanyId])
REFERENCES [dbo].[Address] ([CompanyID])
ON DELETE CASCADE
GO

I tried to add this:

  modelBuilder.Entity<Management>(entity =>
  {
   entity.HasOne(d => d.Company).WithMany(p => p.ManagementSet)
    .HasForeignKey(d => d.CompanyId);
  });

Makes no difference :-(

provider and version information

EF Core version: 7.0.1 Database provider: Microsoft.EntityFrameworkCore.SqlServer Target framework: .NET 7.0 Operating system: Windows

ajcvickers commented 1 year ago

Looks like a bug. /cc @AndriySvyryd

AndriySvyryd commented 1 year ago

A workaround is to edit the generated migration file manually.