2

我在嘗試將以下模型(請參見下圖)轉換爲Code First。我嘗試過涉及ForeignKey和InverseProperty屬性的各種組合,但都沒有運氣。我發現這個answer,但似乎ForeignKey和InverseProperty的組合導致不同的行爲。EF5 InverseProperty問題

附帶的源代碼提供了以下錯誤:

Unable to determine the principal end of an association between the types 'InversePropertyTest.Author' and 'InversePropertyTest.Book'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.

這是我與EDMX模型

Model example

示例代碼:

using System; 
using System.Collections.Generic; 
using System.ComponentModel.DataAnnotations.Schema; 
using System.Data.Entity; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace InversePropertyTest 
{ 
    public class Author 
    { 
     public int AuthorId { get; set; } 
     public Nullable<int> CurrentlyWorkingBookId { get; set; } 

     [InverseProperty("Author")] public ICollection<Book> Books { get; set; } 
     [ForeignKey("CurrentlyWorkingBookId"), InverseProperty("EditoredBy")] public Book CurrentlyWorkingBook { get; set; } 
    } 

    public class Book 
    { 
     public int BookId { get; set; } 
     public int AuthorId { get; set; } 

     [ForeignKey("AuthorId"), InverseProperty("Books")] public Author Author { get; set; } 
     [InverseProperty("CurrentlyWorkingBook")] public Author EditoredBy { get; set; } 
    } 

    public class SimpleContext : DbContext 
    { 
     public DbSet<Author> Authors { get; set; } 
     public DbSet<Book> Books { get; set; } 

     protected override void OnModelCreating(DbModelBuilder modelBuilder) 
     { 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      using (var context = new SimpleContext()) 
      { 
       IList<Author> authors = (from a in context.Authors select a).ToList(); 
       IList<Book> books = (from b in context.Books select b).ToList(); 
      } 
     } 
    } 
} 

任何幫助是極大的讚賞

回答

1

當您在1:1關聯的兩端使用[InverseProperty]時,不清楚主體應該是誰。原則是實體的另一端(依賴)由外鍵引用。儘管你告訴EF EditoredByCurrentlyWorkingBookId都是一個關聯的一部分,但仍有可能在Book中有EditoredBy的外鍵字段(這不會顯示在類模型中)。

不可否認,人們可以爭辯說,你已經告訴過EF足以正確創建數據庫模型。 EF可能有這樣的邏輯:如果我以1:1的關係被告知一個外鍵,那麼我知道誰的原則應該是。然而,不幸的是它沒有。

所以我會用流利的API來模擬這種:

public class Author 
{ 
    public int AuthorId { get; set; } 
    public ICollection<Book> Books { get; set; } 
    public Book CurrentlyWorkingBook { get; set; } 
} 

public class Book 
{ 
    public int BookId { get; set; } 
    public int AuthorId { get; set; } 
    public Author Author { get; set; } 
    public Author EditoredBy { get; set; } 
} 

OnModelCreating

modelBuilder.Entity<Author>() 
      .HasMany(a => a.Books) 
      .WithRequired(b => b.Author) 
      .HasForeignKey(b => b.AuthorId); 
modelBuilder.Entity<Author>() 
      .HasOptional(a => a.CurrentlyWorkingBook) 
      .WithOptionalDependent(b => b.EditoredBy) 
      .Map(m => m.MapKey("CurrentlyWorkingBookId")); 

就個人而言,我喜歡通順API,因爲lambda表達式允許編譯時檢查,並更爲顯眼的是哪一端包含一個關聯。

如您所見,CurrentlyWorkingBookId不能在此場景中成爲類模型的一部分。這是因爲OptionalNavigationPropertyConfiguration(返回類型WithOptionalDependent)沒有HasForeignKey方法。我不確定爲什麼不。我認爲應該可以設置原始FK值(CurrentlyWorkingBookId)以及參考屬性(CurrentlyWorkingBook)。

+0

感謝您的解釋,這正是我需要:) – dna2