Reputation: 1943
This is my first question, I hope is not a dumb one.
I have the following entities here
Customer Companies Phones
public class Customers
{
public Customers()
{
Phones = new List<Phones>();
}
public Guid Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public ICollection<Phones> Phones { get; set; }
}
public class Phones
{
public Guid Id { get; set; }
public string Number { get; set; }
public string Extension { get; set; }
}
public class Companies
{
public Companies()
{
Phones = new List<Phones>();
}
public Guid Id { get; set; }
public string Name { get; set; }
public ICollection<Phones> Phones { get; set; }
}
I want to created with the fluent api a one to many relationship between phones and the same with company and phones.
Upvotes: 1
Views: 9459
Reputation: 806
What you need is what I call association table, you need to make EF create a separate table to hold the relationship details. I do not know if EF is able to do that or not. But in case you are ok with changing your object model then one solution could be to designate specific types for those tables.
public class CustomerPhone
{
public int Id { get; set; }
public Customers Customer { get; set; }
public Phones Phone { get; set; }
}
public class CompanyPhone
{
public int Id { get; set; }
public Companies Company { get; set; }
public Phones Phone { get; set; }
}
Now this classes could hold the relationship, so now you can replace Phone with them:
public class Customers
{
public Customers()
{
Phones = new List<CustomerPhone>();
}
public Guid Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public ICollection<CustomerPhone> Phones { get; set; }
}
public class Companies
{
public Companies()
{
Phones = new List<CompanyPhone>();
}
public Guid Id { get; set; }
public string Name { get; set; }
public ICollection<CompanyPhone> Phones { get; set; }
}
This way you have the opportunity to add more details to your relationship, like creation date etc..
Upvotes: 1
Reputation: 177133
I am not sure if you want the following:
modelBuilder.Entity<Customers>()
.HasMany(c => c.Phones)
.WithOptional()
.Map(m => m.MapKey("CustomerPhoneId"));
modelBuilder.Entity<Companies>()
.HasMany(c => c.Phones)
.WithOptional()
.Map(m => m.MapKey("CompanyPhoneId"));
Using MapKey
is optional. It just gives the foreign key column the name you want. If you omit this EF will create a standard name (something with underscore: ..._Id
).
In fact the whole mapping is optional because the mapping conventions will just create the same relationships without any Fluent API mapping at all.
The Phones
table will have two nullable foreign keys CustomerPhoneId
and CompanyPhoneId
refering to Customers
table and Companies
table respectively.
Edit
An alternative which would only require one foreign key in the Phone
table for multiple different entities would be an inheritance mapping:
public abstract class OrganizationsWithPhone
{
public OrganizationsWithPhone()
{
Phones = new List<Phones>();
}
public Guid Id { get; set; }
public ICollection<Phones> Phones { get; set; }
}
public class Customers : OrganizationsWithPhone
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Companies : OrganizationsWithPhone
{
public string Name { get; set; }
}
public class Phones
{
public Guid Id { get; set; }
public string Number { get; set; }
public string Extension { get; set; }
}
Mapping:
modelBuilder.Entity<OrganizationsWithPhone>()
.HasMany(o => o.Phones)
.WithOptional() // or .WithRequired()
.Map(m => m.MapKey("OrganizationsWithPhoneId"));
modelBuilder.Entity<OrganizationsWithPhone>()
.ToTable("OrganizationsWithPhone");
modelBuilder.Entity<Customers>()
.ToTable("Customers");
modelBuilder.Entity<Companies>()
.ToTable("Companies");
Now you have only one foreign key relationship between Phones
and the base table OrganizationsWithPhone
, but due to the inheritance mapping there are additional one-to-one relationships between the base table and the tables for the derived entities Customers
and Companies
. Basically the number of necessary relationships stays the same (or is even one more in this model).
In this model a customer and a company cannot share the same phone numbers because a row in the Phones
table refers to an OrganizationsWithPhone
which can either be a customer or a company but not both at the same time.
The base table OrganizationsWithPhone
has only a single column Id
. If you have more common properties in all derived entities you can move them into the base entitiy.
Upvotes: 6
Reputation: 6050
See this tutorial -- there are 1 to many relationships between Instructor and Department, between Course and Entrollment, and between Student and Enrollment which you can use as models:
Upvotes: 0