Flash_Back
Flash_Back

Reputation: 565

Entity Framework code first adding extra foreign key

I am completely new to EF Code First approach and I am facing issues regarding Migration result for one for my tables Histories.

I would like the Histories table to have a User foreign key (0..* relation: A user can have none or multiple histories):

public partial class User
{
    public User()
    {
        this.Histories = new HashSet<History>();
    }

    public System.Guid Id { get; set; }

    [InverseProperty("User")]
    public virtual ICollection<History> Histories { get; set; }
}

public partial class History
{
    public History()
    {
    }

    public System.Guid Id { get; set; }
    public System.Guid UserId { get; set; }

    [ForeignKey("UserId")]
    public virtual User User { get; set; }
}

However this migration leads to an extra foreign key User_Id and whatever I try I just can't prevent it from being created.

CreateTable(
            "dbo.Histories",
            c => new
                {
                    Id = c.Guid(nullable: false),
                    UserId = c.Guid(),
                    User_Id = c.Guid(),
                })
            .PrimaryKey(t => t.Id)
            .ForeignKey("dbo.Users", t => t.UserId)
            .ForeignKey("dbo.Users", t => t.User_Id)
            .Index(t => t.UserId)
            .Index(t => t.User_Id);

I'm using Data Annotations but also tried with the OnModelCreating method, unsuccessfully.

I read lots of posts, notably this one (http://www.entityframeworktutorial.net/code-first/configure-one-to-many-relationship-in-code-first.aspx) but couldn't find a working solution.

Would someone please explain me what I am doing wrong and what I have missed ?

Thanks a lot.

Upvotes: 1

Views: 1146

Answers (2)

Miroslav Holec
Miroslav Holec

Reputation: 3217

You could use fluent API this way:

modelBuilder.Entity<History>().HasRequired(x=> x.User).WithMany(x=> x.Histories).HasForeignKey(x=> x.UserId);
modelBuilder.Entity<User>().HasMany(x=> x.Histories).WithRequired(x=> x.User).HasForeignKey(x=> x.UserId);

Property without setter has equal behavior as [NotMapped] attribute.

Upvotes: 0

Flash_Back
Flash_Back

Reputation: 565

I finally figured out what was going on. The InverseProperty is actually needed, otherwise much more extra foreign keys are created, but the issue was due to this property in User other partial class:

public List<History> History
    {
        get
        {
            return Histories.OrderByDescending(h => h.Clock).ThenBy(h => h.Type).ToList();
        }
    }

Adding the [NotMapped] attribute did the trick and prevented the extra foreign key from being added.
I did not know that properties without set would be considered as columns, but seems like that's the case and caused this problem.

Upvotes: 1

Related Questions