2017-02-10 26 views
0

我正在研究實體框架核心。我有兩個簡單的類:CountryCurrency。貨幣應該與國家(法國,德國,意大利等國家都有歐元貨幣)有一對多的關係。如何使用實體框架配置一對多關係核心流利的API

我只想使用流暢的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(){}; 
} 

我定義我的DBSets對象中的DbContext

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

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

,而且我用流利的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導航屬性顯示爲空。

以下代碼獲取正確的國家目標,以「歐元」設置爲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); 

我缺少什麼?

UPDATE

我可以讓我的數據只有當我迫使貨幣DbSet的加載:

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

你嘗試過包括(「貨幣」),而選擇 –

回答

0

你會得到一個空值的原因是,「懶加載」不通過實體框架的核心還不支持:

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

要得到你應使用相關數據「預先加載」:

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

確定讓我來試試@NicolaPrada –

+0

@NicolaPrada請檢查此鏈接。它說EF核心包含了。 https://docs.microsoft.com/en-us/ef/core/querying/related-data –

+0

也檢查這個問題http://stackoverflow.com/questions/38044451/entity-framework-core-eager-loading-那麼包括一個集合 –

相關問題