3

我下面這個教程來實現與EF核心1.1我的友誼系統:http://www.codedodle.com/2014/12/social-network-friends-database.html如何實現自引用與Entity Framework Core 1.1的多對多關係?

Friendship.cs

public class Friendship 
{ 
    public Guid ApplicationUserId { get; set; } 
    public ApplicationUser ApplicationUser { get; set; } 

    public Guid FriendId { get; set; } 
    public ApplicationUser Friend { get; set; } 

    public StatusCode Status { get; set; } 

    public Guid ActionUserId { get; set; } 
    public ApplicationUser ActionUser { get; set; } 

    public byte[] Timestamp { get; set; } 
} 

public enum StatusCode 
{ 
    Pending = 0, 
    Accepted = 1, 
    Declined = 2, 
    Blocked = 3 
} 

ApplicationUser.cs

public class ApplicationUser : IdentityUser<Guid> 
{ 
    ... 

    public ICollection<Friendship> FriendRequestsMade { get; set; } 

    public ICollection<Friendship> FriendRequestsAccepted { get; set; } 

    public byte[] Timestamp { get; set; } 
} 

MyDbContext。 cs

public class SocialCircleContext : IdentityDbContext<ApplicationUser, Role, Guid> 
{ 

    builder.Entity<Friendship>() 
     .HasIndex(x => new { x.ApplicationUserId, x.FriendId }) 
     .IsUnique(); 

    builder.Entity<Friendship>() 
     .HasOne(x => x.ApplicationUser) 
     .WithMany(y => y.FriendRequestsMade) 
     .HasForeignKey(x => x.ApplicationUserId).OnDelete(DeleteBehavior.Restrict); 

    builder.Entity<Friendship>() 
     .HasOne(x => x.Friend) 
     .WithMany(y => y.FriendRequestsAccepted) 
     .HasForeignKey(x => x.FriendId);   
} 

結果的附加遷移InitialMigration

無法確定由類型的導航屬性 'Friendship.ActionUser' 'ApplicationUser' 所代表的關係。要麼手動配置關係,要麼忽略模型中的該屬性。

另外,由於EF Core的移動速度很快,我發現有許多不同的方法可以做到這一點。我不確定自己的多對多關係的實現,有人能給我一些建議嗎?

  1. 如何定義Friendship.ActionUser和ApplicationUser之間的關係?
  2. 任何關於什麼是實現這個自引用多對多關係的正確方法的建議? EF Core的移動速度很快,我在網上發現了很多不同的方式,但它們看起來過時了

謝謝! :)

+0

部分由此提交的錯誤https://github.com/aspnet/EntityFramework/issues/8886 – Smit

回答

1

理想情況下,一旦關係發現中的不明確性得到解決,EF應該按照慣例創建剩餘關係,但不會因錯誤而發生。 (提交Bug

您的模型類對於您要做的事是正確的。爲了使EF成功建立模型,有幾個缺失的部分要填寫。

首先,讓我們來解決你所看到的異常。 您的ApplicationUser類有2個指向Friendship的集合導航。而Friendship班有3個參考導航指向ApplicationUser。雖然EF Core在按慣例創建關係方面做得很好,但在這種情況下,它不知道創建導航逆向導航對的方式。所以用戶輸入需要通過註釋/流利的API。就你而言,你正在使用流暢的API創建2個關係,每個用戶使用2個導航。這使我們只有導航Friendship.ActionUser沒有任何關係。此時,EF Core對於如何建立關係並沒有任何困惑,但是由於它沒有這樣做的缺陷。這意味着你必須使用流暢的API手動配置這種關係。

builder.Entity<Friendship>().HasOne(e => e.ActionUser).WithOne().HasForeignKey<Friendship>(e => e.ActionUserId); 

這會創建一對一的關係。您可以使用HasOne(...).WithMany()創建一對多關係。

這會讓你超過上述錯誤。現在您將看到另一個錯誤,因爲類Friendship沒有定義主鍵。雖然文章說創建一個唯一索引,但對於多對多連接表,連接表配置具有複合PK,以便它可以表示唯一連接。因此,不要像上面那樣調用HasIndex,您應該使用以下代碼。

builder.Entity<Friendship>().HasKey(e => new { e.ApplicationUserId, e.FriendId }); 

上面的代碼後,你可以刪除HasIndex調用,因爲PK始終是唯一的和大多數數據庫對PK定義的索引。

隨着上述變化,你的模型應該很好的工作。

其他事項:因爲由Friendship.ActionUser定義的關係有點含糊不清,因爲它是一對一或一對多的,也許根本不應該是關係。 ActionUserId應取值ApplicationUserIdFriendId的值,您可以通過選擇其中一個導航輕鬆訪問ActionUser。您可以在EF中製作ActionUser [NotMapped],並根據ActionUserId根據返回值ApplicationUser/Friend計算值。雖然這些都是設計選擇。沒有對錯的方法。應該使用哪種方式最有意義,並且以最適合你的方式幫助你。

相關問題