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

Throw exception when shadow principal key is created by convention #3978

Closed
stevejgordon opened this issue Dec 4, 2015 · 3 comments
Closed
Assignees
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-bug
Milestone

Comments

@stevejgordon
Copy link

I'm not sure if this is a bug or just me doing something wrong but if I create a simple entity that can optionally have children of the same type, or a parent of the same type I'm unable to setup the model to produce the correct database.

I have a set of terms which can have child terms under them to build a taxonomy. When I create the migration it produces and additional column for what should be the FK to the parent term. I originally tried with annotations and later with fluent with the same issue.

This is the Term entity

    public class Term
    {
        public int Id { get; set; }
        public int CategoryId{ get; set; }
        public string Name { get; set; }
        public int? ParentId { get; set; }
        public Term Parent { get; set; }
        public ICollection<Term> Children { get; set; }
    }

Fluent model builder

        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            builder.Entity<Term>()
                .HasKey(t => new { t.Id, t.CategoryId });

            builder.Entity<Term>()
                .HasOne(x => x.Parent)
                .WithMany(x => x.Children)
                .HasForeignKey(x => x.ParentId)
                .IsRequired(false);
        }

This is what a snippet of the migration looks like but the issue for me is the non nullable ParentId1

columns: table => new
                {
                    Id = table.Column<int>(nullable: false),
                    CategoryId = table.Column<int>(nullable: false),
                    Name = table.Column<string>(nullable: true),
                    ParentId = table.Column<int>(nullable: true),
                    ParentId1 = table.Column<int>(nullable: false)
                },

I've added a repo with the code to reproduce this to https://github.com/stevejgordon/EF7SelfRefTest

@smitpatel
Copy link
Contributor

The entity Term has a composite primary key defined explicitly. When you explicitly configure relationship to use ParentId as foreign key property, the number of foreign key properties is not equal to number of primary key property of referenced entity (Term), therefore EF will create a shadow property ParentId1 which will be referenced by this foreign key. Hence migration will have extra column ParentId1 and alternate key defined on it.

If you do not want to have shadow property then you need to specify which property to be used as principal key property for the relationship. You need to write something similar to following code:

builder.Entity<Term>()
    .HasOne(x => x.Parent)
    .WithMany(x => x.Children)
    .HasForeignKey(x => x.ParentId)
    .HasPrincipalKey(x => x.Id)      // or whichever property you want to use as principal key property
    .IsRequired(false);

@stevejgordon
Copy link
Author

Many thanks @smitpatel. Can't believe I didn't catch onto that. Have tested it out and it works perfectly. I appreciate the assistance.

@rowanmiller
Copy link
Contributor

@smitpatel this should throw in validation rather than proceeding with a shadow alternate key

@rowanmiller rowanmiller added this to the 7.0.0-rc2 milestone Dec 8, 2015
@smitpatel smitpatel changed the title Self Referencing Entity Throw exception when shadow principal key is created by convention Dec 9, 2015
@ajcvickers ajcvickers modified the milestones: 1.0.0-rc2, 1.0.0 Oct 15, 2022
@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
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-bug
Projects
None yet
Development

No branches or pull requests

4 participants