Reputation: 1040
I'm changing my ASP.NET MVC project to ASP.NET Core MVC with Entity Framework Core and Fluent API. When I try to configure a one-to-one and one-to-many relationship, it generates duplicate foreign key columns in the dependent table.
For example: I have this in my context's OnModelCreating
method:
builder.Entity<Session>()
.HasKey(s=>s.Id);
builder.Entity<Session>()
.Property(s=>s.CourseId)
.IsRequired();
builder.Entity<Session>()
.HasOne<Course>()
.WithMany(c => c.Sessions)
.HasForeignKey(s=>s.CourseId)
.IsRequired();
Session model is like this:
public class Session
{
public int Id { get; set; }
// foreign key
public int CourseId { get; set; }
// navigation properties
public virtual Course Course { get; set; }
}
Course model is like this:
public class Course
{
public int Id { get; set; }
// Navigation properties
public ICollection<Session> Sessions { get; set; }
}
Instead of getting this back in the migration:
modelBuilder.Entity("Blackboard.Models.DomainModels.Session", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("CourseId");
b.HasKey("Id");
b.HasIndex("CourseId");
b.ToTable("Sessions");
});
I get this:
modelBuilder.Entity("Blackboard.Models.DomainModels.Session", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("CourseId");
b.Property<int?>("CourseId1");
b.HasKey("Id");
b.HasIndex("CourseId");
b.HasIndex("CourseId1");
b.ToTable("Sessions");
});
So even though I put .IsRequired();
for the relationship, the relationship seems to be made optional and an optional CourseId1
is added to the table.
The application is developed on Mac OSX with Visual Studio for Mac.
I've been configuring this for so long, I only found something for Entity Framework instead of Entity Framework Core. They two don't configure the same way. Can someone help me please?
Thank you.
Upvotes: 3
Views: 3402
Reputation: 1040
I found a fix. I changed the context to:
builder.Entity<Session>()
.HasOne(s=>s.Course)
.WithMany(c => c.Sessions)
.HasForeignKey(s=>s.CourseId)
.IsRequired();
I remember I saw somewhere saying that if there is only one navigation property, then .HasOne<Type>()
(no parameters passed) can be used. Obviously, it's not working. So always use lambda parameter in .HasOne
.
Upvotes: 4