Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dissalow defining FKs on properties that are part of an inherited key #2837

Closed
AndriySvyryd opened this issue Aug 13, 2015 · 8 comments
Closed
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-unknown
Milestone

Comments

@AndriySvyryd
Copy link
Member

Consider this model:

private class Burger
{
    public int Id { get; set; }
    public Bun Bun { get; set; }
}

private class Ingredient
{
    public int Id { get; set; }
}

private class Bun : Ingredient
{
    public Burger Burger { get; set; }
}

There's an FK from Bun.Id to Burger.Id, however there are no FKs defined from Ingredient. Should Ingredient.Id use its own value generator? Should it use value generator from Burger.Id? What if there's another type derived from Ingredient and it has an FK from Id to a different property? Should we prohibit defining FKs on properties that are part of an inherited key?.

@AndriySvyryd
Copy link
Member Author

@ajcvickers

@rowanmiller
Copy link
Contributor

@AndriySvyryd do we automatically wire up Bun.Id as the FK? Pretty sure we wouldn't have matched that in EF6?

@rowanmiller
Copy link
Contributor

Should we prohibit defining FKs on properties that are part of an inherited key?.

Triage: We agree this sounds reasonable

@rowanmiller rowanmiller added this to the 7.0.0 milestone Aug 14, 2015
@AndriySvyryd AndriySvyryd changed the title Decide on value generation for key properties that are FKs in derived types Dissalow defining FKs on properties that are part of an inherited key Aug 14, 2015
@rowanmiller rowanmiller modified the milestones: 7.0.0-rc1, 7.0.0 Sep 17, 2015
@smitpatel
Copy link
Member

@AndriySvyryd - This would require changes only in ForeignKeyPropertyDiscoveryConvention where searching for candidate fk properties (or compatible pk properties), properties which are part of inherited key won't be matched, right?

@AndriySvyryd
Copy link
Member Author

@smitpatel We should throw in Entity.AddForeignKey()
We should also modify InternalEntityTypeBuilder.HasBaseType() to detect if the new base key conflicts with an fk and try to remove one of them if they do.

@HappyNomad
Copy link

HappyNomad commented Oct 18, 2016

How does this issue relate to EF Core's current codebase? On the one hand, when feeding in my large domain model, I get the exception, "The property 'ID' cannot be part of a foreign key on 'T' because it is contained in a key defined on a base entity type." On the other hand, while trying to understand what this exception means and how to fix it, I tested this issue's original comment's code. I expected it to fail with said exception, but it doesn't.

The data context contains these members:

public DbSet<Burger> Burgers { get; set; }
public DbSet<Ingredient> Ingredients { get; set; }
public DbSet<Bun> Buns { get; set; }

protected override void OnModelCreating( ModelBuilder modelBuilder )
{
    modelBuilder.Entity<Burger>()
        .HasOne( p => p.Bun )
        .WithOne( i => i.Burger )
        .HasForeignKey<Bun>( b => b.BurgerForeignKey );
}

And the model consists of these classes:

public class Burger
{
    public int Id { get; set; }
    public Bun Bun { get; set; }
}

public class Ingredient
{
    public int Id { get; set; }
}

public class Bun : Ingredient
{
    public Burger Burger { get; set; }
    public int BurgerForeignKey { get; set; }
}

And it works! That's weird since I'm still encountering the aforementioned exception when I feed in my more complex model.

@AndriySvyryd
Copy link
Member Author

@HappyNomad That's not the code described in the first post. You need to configure it like this to get the exception:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Burger>()
        .HasOne(p => p.Bun)
        .WithOne(i => i.Burger)
        .HasForeignKey<Bun>(b => b.Id);
}

@HappyNomad
Copy link

@AndriySvyryd Thank you for the correction. Sorry, but I still don't understand why this exception is necessary and how to avoid it. As you see in #6792, I have a model in which this exception is an issue. Although, there's a strange workaround in that small example (but not in my real domain model) that involves renaming a property.

Is the exception necessary due to either (a) a limitation of TPH mapping in general, or (b) the current EF core implementation specifically? I do not know EF Core's implementation, but I am generally familiar with relational databases and TPH mapping.

I do not understand the issue regarding value generation. Please explain the problem more completely, and further illustrate the scenario you are trying to avoid by throwing the exception.

@ajcvickers ajcvickers added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Oct 15, 2022
@ajcvickers ajcvickers modified the milestones: 1.0.0-rc2, 1.0.0 Oct 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-unknown
Projects
None yet
Development

No branches or pull requests

5 participants