Skip to content

Allow Entity Splitting with non-identifying FKs #36251

Description

@Anspitzen

Bug description

Referencing This dokumentation

When declaring the entity splitting with a non-convention foreign key from dependend entity to primary table,
without having an entity for the primary table,
the generated SQL query does ignore the foreign key and just links the primary keys from both tables in the join

public class SqlContext : DbContext
{
public DbSet Dependends { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<DependSplit>(entity =>
    {
        entity.ToTable("Prime", "dbo");
        entity.SplitToTable(
            "Depend", "dbo",
            tb =>
            {
                tb.Property(p => p.SomeValue);
            });
        entity.HasOne<DependSplit>().WithOne().HasForeignKey<DependSplit>(d => d.Primary_ID_ToLink);
    });
}

}

Produces on a Dependents.ToList() the query

SELECT [d].[Id], [d].[Primary_ID_ToLink], [p].[SomeValue]
FROM [dbo].[Depend] AS [d]
INNER JOIN [dbo].[Prime] AS [p] ON [d].[Id] = [p].[Id]

It should be:
SELECT [d].[Id], [d].[Primary_ID_ToLink], [p].[SomeValue]
FROM [dbo].[Depend] AS [d]
INNER JOIN [dbo].[Prime] AS [p] ON [d].[Primary_ID_ToLink] = [p].[Id]

For brevity a lot of other data is left from the code, I just added the minimalist code snippets to get a running sample showcasing the problem
Ids are Identity, the Prime table is independent from the Depend.
Entries in the Prime can exist without a corresponding Id in the Depend
Each Entry in Depend requires an entry in Prime, which will have a different Id (as Prime has many times more entries incremented on key)
I query just the Depend and no Entities from Prime

Your code

(Existing) Database:

CREATE TABLE dbo.Prime (
	Id int NOT NULL PRIMARY KEY,
	SomeValue int NOT NULL
)
CREATE TABLE dbo.Depend (
	Id int NOT NULL PRIMARY KEY,
	Primary_ID_ToLink int NOT NULL,
	FOREIGN KEY (Primary_ID_ToLink) REFERENCES Prime(Id)
)
INSERT INTO dbo.Prime (Id, SomeValue) 
VALUES (1, 1), (2, 2), (3, 3), (4, 4)
INSERT INTO dbo.Depend (Id, Primary_ID_ToLink) 
VALUES (1, 2), (2, 3), (4, 4)

Model:

public class DependSplit
{
    public int Id {  get; set; }
    public int Primary_ID_ToLink {  get; set; }
    public int SomeValue {  get; set; }
}

Ef Core configuration:

public class SqlContext : DbContext
{
    public DbSet<DependSplit> Dependends { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    string SqlConStr = "InsertConnectionStringHere";
    optionsBuilder.UseSqlServer(SqlConStr).LogTo(message => Debug.WriteLine(message));
}
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<DependSplit>(entity =>
        {
            entity.ToTable("Prime", "dbo");
            entity.SplitToTable(
                "Depend", "dbo",
                tb =>
                {
                    tb.Property(p => p.SomeValue);
                });
            entity.HasOne<DependSplit>().WithOne().HasForeignKey<DependSplit>(d => d.Primary_ID_ToLink);
        });
    }
}

Usage:

using (var context = new SqlContext())
{
    var items = await context.Dependends.AsNoTracking().ToListAsync();
}

Stack traces


Verbose output


EF Core version

9.0.2

Database provider

Microsoft.EntityFrameworkCore.SqlServer

Target framework

.NET 8.0

Operating system

No response

IDE

No response

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions