【问题标题】:How to configure one to many relationship using Entity Framework Core fluent API如何使用 Entity Framework Core fluent API 配置一对多关系
【发布时间】:2017-02-10 11:46:07
【问题描述】:

我正在学习 Entity Framework Core。我有两个简单的类:CountryCurrency。货币应与国家(法国、德国、意大利等)具有一对多的关系。它们都共享欧元货币。

我只想使用 fluent API,没有数据注释。目标是使用 LINQ 获取存储在 MYSQL 数据库中的 Country 对象的货币名称。

我定义了我的类:

public class Country
{
    public string CountryID {get; set;} // ISO3166, "US" for United States
    public string CurrencyID {get; set;} // ISO4217 "USD" for US Dollar
    public string Name {get; set;}

    public virtual Currency Currency {get; set;}

    public Country() {};
}

public class Currency
{
    public string CurrencyID {get; set;} // ISO4217
    public string Name {get; set;}

    public virtual ICollection<Country> Countries {get; set;}

    public Currency(){}; 
}

我在 DBContext 中定义了我的 DBSets 对象

public DbSet<Country> Countries {get; set;}

public DbSet<Currency> Currencies {get; set;}

我使用 fluent API 来定义我的数据:

// Country

modelBuilder.Entity<Country>().HasKey(c => new { c.CountryID });
modelBuilder.Entity<Country>().Property(c => c.CountryID).IsRequired();
modelBuilder.Entity<Country>().Property(c => c.CountryID).HasMaxLength(2);
modelBuilder.Entity<Country>().Property(c => c.Name).IsRequired();
modelBuilder.Entity<Country>().Property(c => c.Name).HasMaxLength(50);
modelBuilder.Entity<Country>().Property(c => c.CurrencyID).IsRequired();    //Foreign Key
modelBuilder.Entity<Country>().Property(c => c.CurrencyID).HasMaxLength(3); //Foreign Key

// Currency

modelBuilder.Entity<Currency>().HasKey(c => new { c.CurrencyID });
modelBuilder.Entity<Currency>().Property(c => c.CurrencyID).IsRequired();  
modelBuilder.Entity<Currency>().Property(c => c.CurrencyID).HasMaxLength(3);
modelBuilder.Entity<Currency>().Property(c => c.Name).IsRequired();
modelBuilder.Entity<Currency>().Property(c => c.Name).HasMaxLength(70);

然后我创建了一些默认数据:

using (var dbContext = ContextFactory.Create(connectionString))
{
            {
    dbContext.Add(new Country(iso3166Code: "FR", name: "France", iso4217Code: "EUR"));
    dbContext.Add(new Country(iso3166Code: "DE", name: "Germany", iso4217Code: "EUR"));
    dbContext.Add(new Country(iso3166Code: "IT", name: "Italy", iso4217Code: "EUR"));
    dbContext.Add(new Country(iso3166Code: "US", name: "United States of America", iso4217Code: "USD"));
    dbContext.Add(new Currency(iso4217Code: "EUR", name: "Euro"));
    dbContext.Add(new Currency(iso4217Code: "USD", name: "US Dollar"));

    dbContext.SaveChanges();
}

我确定数据存储在 MYSQL 数据库中并且服务器正在运行。我可以连接到数据库,但是当我尝试时:

var italyCurrencyName = context.Countries.First(c => c.CountryID == "IT").Currency.Name;
WriteLine($"Italy currency is: {italyCurrencyName}");

我得到一个例外:Object reference not set to an instance of an object。原因是 Country 对象的 Currency 导航属性似乎为空。

以下代码获取正确的 Country 对象,“EUR”设置为CurrencyID(外键),但Currency 属性为null

var italy = context.Countries.First(c => c.CountryID == "IT"); 

我试图指定这样的关系但没有成功:

modelBuilder.Entity<Country>().HasOne(e => e.Currency).WithMany(e => e.Countries).HasForeignKey(e => e.CurrencyID);
modelBuilder.Entity<Currency>().HasMany(e => e.Countries);

我错过了什么?

更新

只有在强制加载货币 DbSet 时才能获取数据:

var italy = context.Countries.First(c => c.CountryID == "IT");
var euro = context.Currencies.First(c => c.CurrencyID == "EUR");
WriteLine($"Italy currency is: {italyCurrencyName}");

【问题讨论】:

  • 您是否在选择时尝试了 Include('Currency')

标签: c# entity-framework linq


【解决方案1】:

您获得空值的原因是 Entity Framework Core 尚不支持“延迟加载”:

https://docs.microsoft.com/en-us/ef/core/querying/related-data

要获取相关数据,您应该使用“eager loading”:

var italy = context.Countries.Include(c=>c.Currency).First(c => c.CountryID == "IT");

【讨论】:

  • @NicolaPrada 请检查此链接。它说 EF 核心包含 . docs.microsoft.com/en-us/ef/core/querying/related-data
  • @NicolaPrada 你能解决这个问题还是同样的问题?
  • @NicolaPrada:你能试试我更新了我的答案。请更改货币名称之前的国家/地区。由于 Currency 具有 Country 的导航属性,
  • 这行得通:var italy = context.Countries.Include(c=>c.Currency).First(c => c.CountryID == "IT");
猜你喜欢
  • 2016-06-08
  • 2021-01-19
  • 1970-01-01
  • 2023-01-25
  • 2019-06-18
  • 2013-01-26
  • 2018-02-21
  • 1970-01-01
相关资源
最近更新 更多