One-to-One and One-to-Many Relationships in Entity Framework 5 Code First

I tried all day to get this to work. I learned a lot from the EF Fluent API (for example, this is a great article), but I have not been successful.

I have three objects:

public class Address { [Key] public virtual int AddressId { get; set; } public virtual string AddressString { get; set; } } public class User { [Key] public virtual int UserId { get; set; } public virtual ICollection<Address> Addresses { get; set; } } public class House { [Key] public virtual int HouseId { get; set; } public virtual Address Address { get; set; } } 

and tried all the combinations of HasMany, HasOptional, WithOptional, WithOptionalDependent and WithOptionalPrincipial , which I could think of for both User and House in

 protected override void OnModelCreating(DbModelBuilder modelBuilder) 

I just can't get it to work. I think it should be clear what I want. A user can have more than one address (first of all I want to force at least one, but now I would be happy if the user can have additional addresses ...), and the Domain has only one address - and this is mandatory. It would be nice if the address of the house were cascaded.

+4
source share
2 answers

I believe the following should work for you

 public class Address { public int AddressId { get; set; } public string AddressString { get; set; } } public class User { public int UserId { get; set; } public virtual ICollection<Address> Addresses { get; set; } } public class House { public int HouseId { get; set; } public virtual Address Address { get; set; } } public class TestContext : DbContext { public DbSet<Address> Addresses { get; set; } public DbSet<User> Users { get; set; } public DbSet<House> Houses { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<User>().HasMany(u => u.Addresses).WithMany(); modelBuilder.Entity<House>().HasRequired(h => h.Address).WithOptional().Map(m => m.MapKey("AddressId")); } } 

Please note that it is often better to specify foreign key fields yourself, which can make your life easier. If you do this, you can choose to rewrite the House as follows:

 public class House { public int HouseId { get; set; } public int AddressId { get; set; } public virtual Address Address { get; set; } } 

The convention will bind AddressId and Address. If you have a one-to-one mapping between Home and Address, you can also associate them with primary keys:

 public class House { [ForeignKey("Address")] public int HouseId { get; set; } public virtual Address Address { get; set; } } 

You mentioned that you would like to enforce at least one address β€” this is not possible with a one-to-many relationship. This can only be done if the user had exactly one address, after which you can add the required AddressId property to the User class.

One more comment - you made everything virtual in your code. You only need to make the navigation properties virtual.

+3
source

Something like that:

Apply Address for House :

 modelBuilder.Entity<House>().HasRequired(d => d.Address); 

To create a one-to-many relationship between User and Address :

 modelBuilder.Entity<User>().HasMany(u => u.Addresses).WithMany().Map(x => { x.MapLeftKey("UserId"); x.MapRightKey("AddressId"); x.ToTable("UserAddress"); }); 

What this should do is create a table called UserAddress that maps User to Address .

Alternatively, you can create a POCO for UserAddress yourself and change the corresponding tables:

 public class UserAddress { [Key] public int UserAddressId { get; set; } public User User { get; set; } public Address Address { get; set; } } public User { ... public virtual ICollection<UserAddress> UserAddresses { get; set; } ... } public Address { ... public virtual ICollection<UserAddress> UserAddresses { get; set; } ... } 

Then you need the following: make sure that both User and Address are required:

 modelBuilder.Entity<UserAddress>().HasRequired(u => u.Address); modelBuilder.Entity<UserAddress>().HasRequired(u => u.User); 
+1
source

Source: https://habr.com/ru/post/1444443/


All Articles