簡體   English   中英

如何實現自我引用與Entity Framework Core 1.1的多對多關系?

[英]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的快速發展,我發現了許多不同的方法。 我不確定我實現自我引用的多對多關系,有人可以給我一些建議嗎?

  1. 如何定義Friendship.ActionUser和ApplicationUser之間的關系?
  2. 關於實現這種自我引用多對多關系的正確方法的任何建議? 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應該采用ApplicationUserIdFriendId的值之一,您可以通過選擇其中一個導航輕松訪問ActionUser。 您可以在EF中創建ActionUser [NotMapped] ,並使用基於ActionUserId返回的ApplicationUser/Friend值進行計算。 雖然這些是設計選擇。 沒有正確或錯誤的方式。 應該使用哪個最有意義,並以你消費的方式幫助你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM