2016-07-22 83 views
1

我試圖做實體框架1對1的映射,我發現一個例子online was here, look for the 'Configure One-to-One relationship using Fluent API section'實體框架1對1的關係時,依賴的實體爲null不會拋出異常

大多數網上的例子有點類似於鏈接...以及我在嘗試實現時閱讀的一些書中。

這裏是我的實體:

public class Student 
{ 
    public Student() { } 

    public int StudentId { get; set; } 
    public string StudentName { get; set; } 

    public virtual StudentAddress Address { get; set; } 

} 
public class StudentAddress 
{ 
    public int StudentId { get; set; } 

    public string Address1 { get; set; } 
    public string Address2 { get; set; } 
    public string City { get; set; } 
    public int Zipcode { get; set; } 
    public string State { get; set; } 
    public string Country { get; set; } 

    public virtual Student Student { get; set; } 
} 

,包括使用流利的API配置我的數據方面:

public class DataContext : DbContext 
{ 
    public DbSet<Student> Student { get; set; } 

    // public DbSet<StudentAddress> Addresses { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     // Configure StudentId as PK for StudentAddress 
     modelBuilder.Entity<StudentAddress>() 
      .HasKey(e => e.StudentId); 

     // Configure StudentId as FK for StudentAddress 
     modelBuilder.Entity<Student>() 
        .HasRequired(s => s.Address) 
        .WithRequiredPrincipal(ad => ad.Student); 

    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     using (var context = new DataContext()) 
     { 
      var student = new Student { StudentName = "sample name" }; 
      context.Student.Add(student); 
      context.SaveChanges(); 
     } 
      Console.ReadKey(); 
    } 
} 

在控制檯應用程序,我希望它拋出一個異常,因爲一個學生必須有一個StudentAddress以便保存,但是當我運行應用程序並檢查數據庫時,學生輸入實際上已經保存。我可能會漏掉某些東西......但如果我嘗試在Student類的StudentAddress屬性的頂部添加[Required]屬性,它將引發異常如果我不爲Student Entity提供StudentAddress。

您的反饋/幫助將有很大的幫助,非常感謝。謝謝!

+1

你有它落後。學生地址必須有學生。如果需要StudentAddress來創建學生,那麼您需要創建StudentAddress,因此需要StudentID。如果兩者都必須填充並且關係是1到1,那麼它可能應該是單個表。實際上任何一種人/地址關係都應該是一對多的關係,因爲有很多人擁有超過一個地址。 –

+0

看起來驗證不能用Fluent API進行配置。 –

+0

@DavidCram不,我試圖做的是兩端都需要......這意味着你不能插入一個沒有地址的學生,反之亦然(儘管它只在EF中,因爲你實際上不能在SQL中這樣做)無論如何,應該發生的是,當你調用SaveChanges時它會拋出一個異常? –

回答

1

我提起臭蟲英孚團隊,這裏是解釋爲什麼會這樣。

https://github.com/aspnet/EntityFramework6/issues/66#issuecomment-248073084

從阿瑟·維克斯(在EF開發團隊的成員):

EF總會讓你插入一個新的主體(模型中的學生)沒有任何家屬,無論是否關係是否需要。所需的關係意味着,如果沒有相應的委託人,則不能插入依賴項(模型中的地址)。我意識到,在EF6中建立關係模式意味着不同,但以這種方式描述關係,然後表現得像這樣的決定是多年前制定的,現在我們不能改變它。

0

嘗試刪除關係主體的聲明。根據我的經驗,如果你使用註解,只需要/屬性來創建1-1的關係:

modelBuilder.Entity<Student>() 
    .HasRequired(s => s.Address); 
+0

我的觀點正是......它應該是1-1這意味着你不能在沒有其他實體的情況下保存任何實體(至少在調用SaveChanges的實體框架中) –

+0

我期望它會拋出一個異常......如果添加兩個實體的導航屬性的必需屬性。 hmmmmm :) –

+1

就目前而言,上述更改會創建外鍵約束違規,因此當您嘗試添加沒有StudentAddress的學生時會引發異常。 由於您已將DBSet註釋爲「地址」,因此無法添加StudentAddress而無需創建學生並在保存之前將StudentAddress添加到新學生。你能解釋一下這不能滿足你的需求嗎? (順便說一下,這不會使用任何註釋,如您所請求的那樣。) –

0

在一到一個關係一端必須是委託人和第二端必須依賴。主要目標是先插入並且可以不依賴於目標的目標。依賴性結束是必須在委託人之後插入的結果,因爲它具有委託人的外鍵。

因此,嘗試刪除此:

.WithRequiredPrincipal(ad => ad.Student); 

.WithRequiredDependent(ad => ad.Student); 

,也可以刪除該行或在財產使用[Required]數據註解...

+0

好吧...目標是實際上在不使用數據註釋的情況下實現了它。再次...我期望我的代碼拋出一個異常,因爲這兩個實體都是必需的,所以應該發生的是,一旦你調用SaveChanges,異常應該拋出類似的,如果我對我的實體的導航屬性放置必需的屬性。 –

+0

好的,你試過這個:'modelBuilder.Entity () .HasKey(e => e.StudentId).HasRequired(s => s.Student); modelBuilder.Entity () .HasRequired(s => s.Address);' –

+0

這將產生一個表明它不能確定實體之間的主要關聯。 –