Let’s assume I have these tables:
Role
- RoleId
- Name
UserRole
- UserId
- RoleId
User
- UserId
- Username
UserEmail
- UserId
- EmailId
- IsPrimary
Email
- EmailId
- Address
Now my model, should look something like this:
public class Role {
public int RoleId { get; set; }
public string Name { get; set; }
public virtual ICollection<User> Users { get; set; }
}
public class User {
public int UserId { get; set; }
public string Username { get; set; }
public virtual ICollection<Role> Roles { get; set; }
public virtual ICollection<UserEmail> UserEmails { get; set; }
}
public class UserEmail {
public int UserId { get; set; }
public int EmailId { get; set; }
public bool IsPrimary { get; set; }
public virtual User User { get; set; }
public virtual Email Email { get; set; }
}
public class Email {
public int EmailId { get; set; }
public string Address { get; set; }
public virtual ICollection<UserEmail> UserEmails { get; set; }
}
These are common and specific things I would like to do in this particular case:
Add the primary keys:
modelBuilder.Entity<Role>().HasKey(q => q.RoleId);
Will this have the same effect than using the Key attribute in the entity property? If so, why bother using the modelBuilder when using Data Annotations is shorter and easier to read/write? Is there any convention on when to use Data Annotations or Fluent API?
Add many to many relationships:
modelBuilder.Entity<Role>()
.HasMany(q => q.Users)
.WithMany(q => q.Roles)
.Map(q => {
q.MapLeftKey("RoleId");
q.MapRightKey("UserId");
q.ToTable("UserRoles");
});
Add one to many relationships:
modelBuilder.Entity<UserEmail>()
.HasRequired(q => q.User)
.WithMany(q => q.UserEmails)
.HasForeignKey(q => q.EmailId);
Is the last line required?
Yes, that
HasKeymethod has the same effect as the[Key]attribute. You might have a lot of configuration to do and prefer to keep it all in theModelBuildermethod. On the other hand you might have very little or prefer to use the attributes for some of it. Just gives you some flexibility.If you’re talking about the:
.HasForeignKey(q => q.EmailId);Then in your case, yes it is required. Why? Because you’ve created your own foreign key property in the
UserEmailentity. If you deleted the property you could remove this line and EF would create one for you in the database calledEmail_Id. You could still access this through the navigation propertyinstanceOfUserEmail.Email.EmailId.