【问题标题】:Cannot create a relationship when using two FK使用两个 FK 时无法创建关系
【发布时间】:2019-03-24 17:05:20
【问题描述】:

我在我的ASP.Net Core 应用程序中使用EF,我正在尝试将UserNotification 表关联到我的User 表。这些是表结构:

public class User : IdentityUser
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public virtual UserNotifications { get; set; }
}

public class UserNotifications
{
    public int Id { get; set; }

    [Key, ForeignKey("User")]
    public string UserId { get; set; }
    public User User { get; set; }

    [Key, ForeignKey("Sender")]
    public string SenderId { get; set; }
    public virtual User Sender { get; set; }      

    public string Title { get; set; }
    public string Message { get; set; }
}

我所做的是创建UserNotificationsForeignKey,我将存储User 收到的所有通知。

UserNotifications 表中,我为UserSender 创建了两个FK。本质上,我想存储已收到通知的UserId,以及已发送通知的UserId (Sender)。

OnModelCreating里面我还定义了如下逻辑:

builder.Entity<UserNotifications>(entity =>
{
    entity.HasKey(n => n.Id);
    entity.HasOne(u => u.User)
          .WithOne(u => u.UserNotifications)
          .HasForeignKey<User>(u => u.Id);

    entity.HasOne(u => u.Sender)
          .WithOne(u => u.UserNotifications)
          .HasForeignKey<User>(u => u.Id);
 });

当我在console 中键入以下建筑物时:

add-migration InitialMigration -context MyAppContext

我明白了:

无法在“User.UserNotifications”和“UserNotifications.Sender”之间创建关系,因为“UserNotifications.User”和“User.UserNotifications”之间已经存在关系。导航属性只能参与单个关系。

我是EntityFramework 的新手,所以我不知道如何解决这个问题,有人可以解释我做错了什么吗?

提前感谢您的帮助。

【问题讨论】:

  • 什么是public virtual UserNotifications { get; set; }
  • 我认为是一个集合,属性名称是复数,但让我们等待@Rockj 响应

标签: asp.net entity-framework asp.net-core entity-framework-core


【解决方案1】:

您描述的模型表示UserUserNotifications(顺便说一句,实体应命名为UserNotification)实体之间的两个 一对多关系。每个 EF 关系可以在每一侧映射到 0 或 1 个唯一的导航属性。

您已经在UserNotifications 中有两个 UserSender 引用导航属性(和相应的外键)。你需要的是User两个对应的集合导航属性:

public class User : IdentityUser
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public virtual ICollection<UserNotifications> ReceivedNotifications { get; set; }
    public virtual ICollection<UserNotifications> SentNotifications { get; set; }
}

并使用流畅的 API 进行映射:

builder.Entity<UserNotifications>(entity =>
{
    entity.HasKey(n => n.Id);

    entity.HasOne(n => u.User)
        .WithMany(u => u.ReceivedNotifications)
        .HasForeignKey(n => u.UserId)
        .IsRequired()
        .OnDelete(DeleteBehavior.Delete);

    entity.HasOne(n => n.Sender)
        .WithMany(u => u.SentNotifications)
        .HasForeignKey(n => n.SenderId)
        .IsRequired()
        .OnDelete(DeleteBehavior.Restrict);
 });

请注意,由于此类模型引入了所谓的多级联路径,因此您需要关闭至少一个级联删除并手动处理。

【讨论】:

    猜你喜欢
    • 2018-07-31
    • 2012-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多