I have a problem with setting up a one-to-many relation with EF Core.
I have two tables address
and address_country
. There are schemas:
As you see, I want to store countries with different locales. So it has a composed key. address
table has a foreign key to address_country
. Unfortunately, I cannot setup ContextDb
to achieve what I want. The list of countries is not filled in Address
model.
I have the following code in Context
:
public class Context : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite(
@"Data Source=addresses.db");
base.OnConfiguring(optionsBuilder);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<AddressDto>()
.ToTable("address");
modelBuilder.Entity<CountryLocaleDto>()
.ToTable("address_country");
modelBuilder.Entity<CountryLocaleDto>()
.HasKey(cl => new {cl.Id, cl.Locale});
base.OnModelCreating(modelBuilder);
}
public DbSet<AddressDto> Addresses { get; set; }
}
And my models are
public class AddressDto
{
public int Id { get; set; }
public int CountryId { get; set; }
public List<CountryLocaleDto> CountryLocale { get; set; }
}
public class CountryLocaleDto
{
public int Id { get; set; }
public string Locale { get; set; }
}
There is no exception. I simply don't know how to configure this kind of relation. Can anyone help me with that, please?
Example data would be:
address
id | countryId |
---|---|
1 | 1 |
2 | 1 |
address_country
id | locale | name |
---|---|---|
1 | 'en' | 'Germany' |
1 | 'de' | 'Deutschland' |
An example solution with SQLite db can be found with this link.
If I got you right - you just need to add this code to your context class
modelBuilder.Entity<AddressDto>()
.HasMany(e=>e.CountryLocale)
.WithOne()
.HasForeignKey(x=>x.Id)
.HasPrincipalKey(x=>x.CountryId);
Here you have to add HasForeignKey and HasPrincipalKey
The Entity Framework Core Fluent API HasForeignKey method is used to specify which property is the foreign key in a relationship.
Principal key: The property(s) that uniquely identifies the principal entity. This may be the primary key or an alternate key. Navigation property: A property defined on the principal and/or dependent entity that contains a reference(s) to the related entity(s).
your model should look like that
public class AddressDto
{
public int Id { get; set; }
public int CountryId { get; set; }
public List<CountryLocaleDto> CountryLocale { get; set; }
}
public class CountryLocaleDto
{
public int Id { get; set; }
public string Locale { get; set; }
}
I mean you don't have to add anything else in your model.
I hope it was helpful.
P.S. Appreciate adding the sample project