Reputation: 703
I have two classes: One is User
public class User
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public List<Subscription> Subscriptions { get; set; }
}
Other is Subscription:
public class Subscription
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
As you can see that User has a list of Subscriptions. Now when using the entity framework code first approach I am getting a table for User which doesn't contain Subscriptions but a new column for User Id is being added to Subscription table. I was expecting to have a third table which contains two columns one with User ID and the other with subscription ID. How can I achieve this?
Upvotes: 4
Views: 2430
Reputation: 8637
From documentation:
Many-to-many relationships without an entity class to represent the join table are not yet supported. However, you can represent a many-to-many relationship by including an entity class for the join table and mapping two separate one-to-many relationships.
So this answer is correct.
I just corrected code a little bit:
class MyContext : DbContext
{
public DbSet<Use> Users { get; set; }
public DbSet<Subscription> Subscriptions { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<UserSubscription>()
.HasKey(t => new { t.UserId, t.SubscriptionId });
modelBuilder.Entity<UserSubscription>()
.HasOne(pt => pt.User)
.WithMany(p => p.UserSubscription)
.HasForeignKey(pt => pt.UserId);
modelBuilder.Entity<UserSubscription>()
.HasOne(pt => pt.Subscription)
.WithMany(t => t.UserSubscription)
.HasForeignKey(pt => pt.SubscriptionId);
}
}
public class User
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public List<UserSubscription> UserSubscriptions{ get; set; }
}
public class Subscription
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public List<UserSubscription> UserSubscriptions{ get; set; }
}
public class UserSubscription
{
public int UserId { get; set; }
public User User { get; set; }
public int SubscriptionId { get; set; }
public Subscription Subscription { get; set; }
}
PS. You don't need use virtual in navigation property, because lazy loading still not available in EF Core.
Upvotes: 3
Reputation: 5943
Create a third middle table named: UserSubscriptions
for example.
public class User
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public virtual ICollection<UserSubscription> Subscriptions { get; set; }
}
public class Subscription
{
public int ID { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
public class UserSubscription
{
public int ID { get; set; }
public int SubscriptionID { get; set; }
public decimal Price { get; set; }
public int UserID { get; set; }
public virtual User { get; set; }
public DateTime BeginDate { get; set; }
public DateTime EndDate { get; set; }
}
Second Solution:
Add reference for Subscription
to User
and name it CurrentSubscription
for example.
public class User
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public int CurrentSubscriptionID { get; set; }
public virtual Subscription Subscription { get; set; }
}
public class Subscription
{
public int ID { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
Upvotes: 1