EF核心种子数据库OneToMany关系与预定义的列表

问题描述 投票:0回答:1

我试图在我的数据库中用定义的List<&gt播种一个OneToMany关系,但我得到了以下的错误信息。

'实体类型'国家'的种子实体无法添加,因为它有导航'WineRegions'设置。要建立种子关系,需要将相关实体种子添加到'WineRegion',并指定外键值{'CountryId'}。可以考虑使用'DbContextOptionsBuilder.EnableSensitiveDataLogging'来查看涉及的属性值。

我使用这个页面来创建我的类。https:/www.learnentityframeworkcore.comrelationships#one-to-many... 我只能猜测我需要手动定义键,尽管它应该自动工作......

这是我的两个类。WineRegions包含一个国家,Country包含一个WineRegions的集合。

public class WineRegion
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int WineRegionId { get; set; }

    public string WineRegionName { get; set; }   

    public int CountryId { get; set; }
    public Country Country { get; set; }
}

public class Country
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int CountryId { get; set; }

    [Required]
    [MaxLength(255)]
    public string CountryName { get; set; }

    [Required]
    [MaxLength(2)]
    public string ISO3166Alpha2 { get; set; }

    public ICollection<WineRegion> WineRegions { get; set; }
}

在播种过程中,我不想使用硬编码的对象,比如(顺便说一句,这段代码可以用...)。

        modelBuilder.Entity<Country>().HasData(
            new { Id = 1, Name = "France", ISO3166Alpha2 = "FR" }
            );

        modelBuilder.Entity<WineRegion>().HasData(
            new { Id = 1, Name = "Bordeaux", CountryId = 1 }
            );

正如我之前提到的,我想使用列表,在JSON解析过程中生成。

所以我是这样做的。

        modelBuilder.Entity<Country>().HasData(listOfCountries);  // List<Country>
        modelBuilder.Entity<WineRegion>().HasData(listOfWineRegions); //List<WineRegion>

我的JSON看起来是这样的。

  "wineregions": [
    {
      "id": 1,
      "country": "France",
      "iso2": "FR",
      "region": [
        {
          "id": 1,
          "name": "Bordeaux"
        },
        {
          "id": 2,
          "name": "Burgundy"
        },
        {
          "id": 4,
          "name": "Burgundy"
        },
        {
          "id": 5,
          "name": "Beaujolais"
        },
        {
          "id": 6,
          "name": "Champagne"
        },
        {
          "id": 7,
          "name": "Loire"
        },
        {
          "id": 8,
          "name": "Alsace"
        },
        {
          "id": 9,
          "name": "Rhône"
        },
        {
          "id": 10,
          "name": "Provence"
        },
        {
          "id": 11,
          "name": "Languedoc-Roussillon"
        },
        {
          "id": 12,
          "name": "Jura"
        }
      ]
    },
    {
      "id": 2,
      "country": "Italy",
      "iso2": "IT",
      "region": [
        {
          "id": 1,
          "name": "Piedmont"
        },
        {
          "id": 2,
          "name": "Barolo"
        },
        {
          "id": 3,
          "name": "Barbaresco"
        },
        {
          "id": 4,
          "name": "Tuscany"
        },
        {
          "id": 5,
          "name": "Veneto"
        },
        {
          "id": 6,
          "name": "Friuli-Venezia"
        },
        {
          "id": 7,
          "name": "Giulia"
        },
        {
          "id": 8,
          "name": "Abruzzo"
        },
        {
          "id": 9,
          "name": "Sicily"
        },
        {
          "id": 10,
          "name": "Lambrusco"
        }
      ]
    }
  ]
} 


Thanks in advance
c# asp.net one-to-many seeding ef-core-3.0
1个回答
1
投票

你的 WineRegionIdConutryId 当你的数据库键是Identity时,它由SQL自动生成。

当您的数据库键是身份信息时 Id = 1 工作。

你应该把身份从 CountryIdWineRegionId.

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int CountryId { get; set; }
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int WineRegionId { get; set; }

另一种方式

你可以把你的代码改成这样。

Country country = new Country { Name = "France", ISO3166Alpha2 = "FR" };
modelBuilder.Entity<Country>().HasData(country);

modelBuilder.Entity<WineRegion>().HasData(
            new { Name = "Bordeaux", Country = country }
            );

在这种情况下 ConutryIdWineRegionId 自动生成的 SQL 和之间的关系 ConutryWineRegion 这一行

new { Name = "Bordeaux", Country = country/*<--NOTE THIS*/ }

0
投票

所以我想出了如何解决这个问题,但我不太明白为什么要这样......在此向Farhad Zamani表示感谢!我把身份属性改成了::。

  1. 我把身份属性改成了:[DatabaseGenerated(DatabaseGeneratedOption)]。[DatabaseGenerated(DatabaseGeneratedOption.None)] --
  2. 我需要从两个类中删除[关键]属性。
  3. 我需要将[NotMapped]属性应用到嵌套在WineRegion类中的Country类。
  4. 我需要将ForeignKey属性应用到CountryId属性中。

    public class WineRegion
    {
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int WineRegionId { get; set; }
    
    public string WineRegionName { get; set; }
    
    [NotMapped]
    public Country Country { get; set; }
    
    [ForeignKey("CountryId")]
    public int CountryId { get; set; }
    }
    
    public class Country
    {
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int CountryId { get; set; }
    
    [Required]
    [MaxLength(255)]
    public string CountryName { get; set; }
    
    [Required]
    [MaxLength(2)]
    public string ISO3166Alpha2 { get; set; }
    
    public List<WineRegion> WineRegions { get; set; }
    }
    
© www.soinside.com 2019 - 2024. All rights reserved.