How should I define relationships using Code First but without using any navigation properties?
Previously I have defined One-Many and Many-Many by using navigation properties in both ends of the relationship. And the appropriate relationships are created in the database. here's a stripped down version of how the classes look like (I've converted the Many-Many relationships to one-many for simplicity).
public class User
{
public string UserId { get; set; }
public string PasswordHash { get; set; }
public bool IsDisabled { get; set; }
public DateTime AccessExpiryDate { get; set; }
public bool MustChangePassword { get; set; }
public virtual Role Role { get; set; }
}
public class Role
{
public int RoleId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual ICollection<User> Users { get; set; }
public virtual ICollection<Right> Rights { get; set; }
}
public class Right
{
public Guid RightId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual Role Role { get; set; }
}
However, if I remove the navigation properties, no relationships are being created. Here's how the classes would look like.
public class User
{
public string UserId { get; set; }
public string PasswordHash { get; set; }
public bool IsDisabled { get; set; }
public DateTime AccessExpiryDate { get; set; }
public bool MustChangePassword { get; set; }
public int Role RoleId { get; set; }
}
public class Role
{
public int RoleId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
public class Right
{
public Guid RightId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int RoleId { get; set; }
}
notice that instead of a navigation property, I have the primary key of the related table. Everything gets created on the table - except the relationship. So how do I get about doing this?
BTW, I've tried various combinations in the OnModelCreating method of the dbcontext but to no avail. Any help is much appreciated!
Thanks, Mel
I believe you always need navigation property on at least one side when using code-first. Then you will be able to map it:
public class User
{
public string UserId { get; set; }
public string PasswordHash { get; set; }
public bool IsDisabled { get; set; }
public DateTime AccessExpiryDate { get; set; }
public bool MustChangePassword { get; set; }
public int RoleId { get; set; }
public Role Role { get; set; }
}
public class Role
{
public int RoleId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
public class Right
{
public Guid RightId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int RoleId { get; set; }
public Role Role { get; set; }
}
public class TestContext : DbContext
{
public TestContext() : base("Entities")
{}
protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<User>()
.HasRequired(r => r.Role)
.WithMany()
.HasForeignKey(r => r.RoleId);
modelBuilder.Entity<Right>()
.HasRequired(r => r.Role)
.WithMany()
.HasForeignKey(r => r.RoleId);
}
}
You can use the fluent api to add the relationship, though the "configuration" code is separate from the entity code making it less discoverable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With