I'm trying to use code-first
to model my db.
What I'm trying to map here is a 0 -> *
relationship for Users
and Challenges
.
E.g A user can have 0 or more challenges associated with them. A challenge can have 0 or more users associated with them.
This is the code I'm using, the problem is that the challenges table is generated with a UserAccount_ID
property.
public class UserAccount
{
public int Id { get; set; }
public string Username { get; set; }
public virtual List<Challenge> Challenges { get; set; }
}
public class Challenge
{
public int Id { get; set; }
public string ChallengeId {get; set;}
public string Name { get; set; }
public string Description { get; set; }
public virtual List<Competitor> Competitors { get; set; }
}
public class Competitor
{
public int Id { get; set; }
public string Username { get; set; }
public int Rank { get; set; }
}
And the incorrect property:
I've tried adding this to my context class but it doesn't have any effect:
protected override void OnModelCreating(DbModelBuilder mb)
{
mb.Entity<UserAccount>()
.HasMany(o1 => o1.Challenges)
.WithOptional();
base.OnModelCreating(mb);
}
Edit
Updated title and question - relationship is not zero to many but many to many.
That column comes from your relationship between Challenge
and UserAccount
. You could declare the FK property in your model:
public class Challenge
{
public int Id { get; set; }
public string ChallengeId {get; set;}
public string Name { get; set; }
public string Description { get; set; }
//Add these properties
public int UserAccountId{get;set;}
public UserAccount UserAccount{get;set;}
public virtual List<Competitor> Competitors { get; set; }
}
By default EF use some name conventions to identify the FK properties in your model, so it should be fine with that name. Now, if you are using Fluent Api, then I suggest to configure the relationship as you are intending to do:
protected override void OnModelCreating(DbModelBuilder mb)
{
mb.Entity<UserAccount>()
.HasMany(o1 => o1.Challenges)
.WithOptional(e=>e.UserAccount);
.HasForeignKey(e=>e.UserAccountId);
base.OnModelCreating(mb);
}
Now if you don't want to include the FK property and the navigation property in your Challenge entity but you want to rename the FK property you can do this:
protected override void OnModelCreating(DbModelBuilder mb)
{
mb.Entity<UserAccount>()
.HasMany(o1 => o1.Challenges)
.WithOptional();
.Map(m => m.MapKey("UserAccountId"));
base.OnModelCreating(mb);
}
Thinking a little more about your model it is true that maybe what you are really pursuing is a many to many relationship, if that if the case you can configure this way:
mb.Entity<UserAccount>()
.HasMany(r => r.Challenges)
.WithMany() // No navigation property here
.Map(m =>
{
m.MapLeftKey("UserAccountId");
m.MapRightKey("ChallengeId");
m.ToTable("UserAccountChallenge");
});