与具有多行的fk建立一对多关系

与EF Core建立一对多关系时遇到问题。
我有两个表addressaddress_country。有模式:

与具有多行的fk建立一对多关系


与具有多行的fk建立一对多关系


如您所见,我想存储具有不同语言环境的国家。因此它具有组合键。 address表具有address_country的外键。不幸的是,我无法设置ContextDb来实现自己想要的功能。 Address模型中未填写国家/地区列表。
我在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; }
}

我的模特是

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; }
}

也不例外。我根本不知道如何配置这种关系。有人可以帮我吗?
示例数据为:
地址(id,countryId)
(1,1)
(2,1)
address_country(ID,语言环境,名称)
(1,'en','Germany')
(1,'de','Deutschland')
使用this link可以找到SQLite db的示例解决方案。

wan_XM 回答:与具有多行的fk建立一对多关系

如果我说对了-您只需要将此代码添加到上下文类中

modelBuilder.Entity<AddressDto>()
            .HasMany(e=>e.CountryLocale)
            .WithOne()
            .HasForeignKey(x=>x.Id)
            .HasPrincipalKey(x=>x.CountryId);

在这里您必须添加 HasForeignKey HasPrincipalKey

实体框架核心Fluent API HasForeignKey 方法用于指定关系中的哪个属性是外键。

主键:唯一标识主实体的属性。这可以是主键或备用键。 导航属性:在主体和/或从属实体上定义的属性,其中包含对相关实体的引用。

您的模型应该像这样

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; }
}

我的意思是您不必在模型中添加任何其他内容。

我希望这会有所帮助。

P.S。赞赏添加示例项目

,

我现在可以看到您的问题。如果address具有指向address_country的外键,则意味着一个AddressDto只能有一个CountryLocaleDto。如果您希望一个address连接到鬃毛address_country,则在您的address_country中,您应该有一个指向address的外键

如果要建立多对多关系,则需要一个中介表address_country_address

如果采用第一个解决方案,则可以在AddressId中添加address_country列,并像这样扩展CountryLocaleDto

public class CountryLocaleDto
{
    public int Id { get; set; }
    public string Locale { get; set; }
    public int AddressId {get; set;}
}

然后执行以下操作?

modelBuilder.Entity<AddressDto>()
    .HasMany(c => c.CountryLocaleDto)
    .WithOne(a => a.AddressDto);
    .HasForeignKey(a => a.CountryId);
    .HasPrincipalKey(c => c.Id);

通常,这就是我们向多个CountryLocale声明一个地址的方式。

编辑

评论后,我们发现address表中有一个CountryId列。

由于我们需要将Principal密钥从一个更改为另一个,因此我们需要使用alternate keys solution from microsoft.

  

按惯例发现的关系将始终以   主体的主键。要定位备用键,   必须使用Fluent API执行其他配置。

,
    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; }
        public int AddressDtoId {get; set;}
        public AddressDto Address {get; set;}
    }

   modelBuilder.Entity<CountryLocaleDto>()
                .HasOne(p => p.Address)
                .WithMany(b => b.CountryLocale);

这应该配置一对多的关系,并向多个国家/地区分配一个地址。

此来源为:https://docs.microsoft.com/en-us/ef/core/modeling/relationships#fluent-api

同样,您可以执行以下操作,并从CountryLocaleDto中删除AddressDto属性:

            modelBuilder.Entity<CountryLocaleDto>(model =>
            {
                model.HasOne<AddressDto>()
                      .WithMany()
                      .HasForeignKey(x => x.AddressDtoId);
            });

更新:

modelBuilder.Entity<AddressDto>()
                .HasMany(b => b.CountryLocale)
                .WithOne();

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; }
        }

来源:https://docs.microsoft.com/en-us/ef/core/modeling/relationships-单个导航属性

本文链接:https://www.f2er.com/3081079.html

大家都在问