[英]Entity Framework Core 3.0 - Creating a self-referencing many to many relationship
[英]How to implement an self referencing many to many relationship with Entity Framework Core 1.1?
我正在按照本教程使用EF Core 1.1實現我的友誼系統: http : //www.codedodle.com/2014/12/social-network-friends-database.html
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);
}
Add-Migration InitialMigration的結果
無法確定“ApplicationUser”類型的導航屬性“Friendship.ActionUser”所代表的關系。 手動配置關系,或從模型中忽略此屬性。
此外,隨着EF Core的快速發展,我發現了許多不同的方法。 我不確定我實現自我引用的多對多關系,有人可以給我一些建議嗎?
謝謝! :)
理想情況下,一旦關系發現中的歧義得到解決,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
定義的Friendship.ActionUser
有點模棱兩可,因為它可能是一對一或一對多,也許它根本不應該是一種關系。 ActionUserId應該采用ApplicationUserId
或FriendId
的值之一,您可以通過選擇其中一個導航輕松訪問ActionUser。 您可以在EF中創建ActionUser [NotMapped]
,並使用基於ActionUserId
返回的ApplicationUser/Friend
值進行計算。 雖然這些是設計選擇。 沒有正確或錯誤的方式。 應該使用哪個最有意義,並以你消費的方式幫助你。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.