【问题标题】:Code first migration modeling class with two AppUser references具有两个 AppUser 引用的代码优先迁移建模类
【发布时间】:2017-11-14 00:12:38
【问题描述】:

我正在尝试使用代码优先迁移为用户的私人消息建模消息类。

public class Message
{
     public int MessageId { get; set; }

    [Required]
    public string MessageForUserId { get; set; }
    public virtual ApplicationUser MessageForUser { get; set; }

    [Required]
    public string MessageFromUserId { get; set; }

    public virtual ApplicationUser MessageFromUser { get; set; }

    [Required]
    public string MessageContent { get; set; }

    public bool MessageRead { get; set; }

    [Required]
    public DateTime MessageCreatedOn { get; set; }

    public DateTime? MessageReadOn { get; set; }
}

在 ApplicationUser 类中我添加了两个集合

public class ApplicationUser : IdentityUser
{
    // other properties removed for brevity
    public ICollection<Message> UserMessages { get; set; }
    public ICollection<Message> SentMessages { get; set; }
}

当我进行迁移时,我不仅获得了 MessageFrom 和 MessageFor Id,还向 Message 表添加了两个额外的 Id ApplicationUser_Id 和 ApplicationUser_Id1。

我知道这是因为它们是消息中的两个外键。由于我在迁移时遇到错误,外键注释现在被注释掉了。

这是 ForeignKeys 处于活动状态并且我尝试迁移时的错误。

无法确定“ICollection”类型的导航属性“ApplicationUser.UserMessages”表示的关系。手动配置关系,或使用“[NotMapped]”属性或使用“OnModelCreating”中的“EntityTypeBuilder.Ignore”忽略此属性。

我想使用流利的注释在 OnModelCreating 方法中定义这个类,但不知道如何正确地做到这一点。我显然不明白为什么 EF Code First 没有确定关系。

问题是我不确定如何定义消息类外键。每条消息都涉及两个用户,即发送者和接收者。我曾考虑将消息分成两个类,MessageSent 和 MessageReceived,但这无济于事,因为它们中的每一个都有一个发送者和接收者。

任何有关如何使用流畅注释正确定义的帮助将不胜感激。

更新:

按照 Dominick 的建议和之前的帖子参考,我尝试了以下方法,但不起作用。

这是 DbSet 代码

 public DbSet<Message> Messages { get; set; }
 public DbSet<ApplicationUser> AppUsers { get; set; }

在 OnModelCreating 中

 builder.Entity(typeof(Message))
            .HasOne(typeof(ApplicationUser), "MessageFromUser")
            .WithMany()
            .HasForeignKey("MessageFromUserId")
            .OnDelete(DeleteBehavior.Restrict); // no ON DELETE

 builder.Entity(typeof(Message))
            .HasOne(typeof(ApplicationUser), "MessageForUser")
            .WithMany()
            .HasForeignKey("MessageForUserId")
            .OnDelete(DeleteBehavior.Cascade); // set ON DELETE CASCADE

我得到了与上面提到的相同的错误,即使构建器选项是有意义的。该实体有一种 ApplicationUser,MessagesFromUser,可以有很多,并且外键 id 是正确的。其他属性也是如此。

【问题讨论】:

  • @Dominik Szymanski... 那篇文章没有出现在我的搜索中,感谢您的参考。它看起来是正确的解决方案。我正在使用 .Net Core 2.0 和 EF Core 2。实体构建器中的 HasRequired 似乎已被弃用。我是否缺少库参考,或者是现在定义它的另一种方式。 Resharper 没有向我显示 HasRequired 的有效库。
  • 请看这个:stackoverflow.com/questions/35098204/… 这不是您要问的问题,但有您需要的解决方案和您潜在问题的解决方案。
  • @Dominik Szymanski... 那篇文章也很有帮助,而且非常相似。我相应地调整了我的代码,请参阅帖子中的更新,但我得到了同样的错误。
  • 我搞定了,需要将 Icollection 实体添加到 WithMany 调用中,即 builder.Entity(typeof(Message)) .HasOne(typeof(ApplicationUser), "MessageFromUser") .WithMany("SentMessages ") .HasForeignKey("MessageFromUserId") .OnDelete(DeleteBehavior.Restrict);

标签: c# annotations ef-code-first


【解决方案1】:
builder.Entity<Message>()
    .HasOne(x => x.MessageForUser)
    .WithMany(x => x.UserMessages)
    .HasForeignKey(x => x.MessageForUserId)
    .OnDelete(DeleteBehavior.Cascade);

builder.Entity<Message>()
    .HasOne(x => x.MessageFromUser)
    .WithMany(x => x.SentMessages)
    .HasForeignKey(x => x.MessageFromUserId)
    .OnDelete(DeleteBehavior.Cascade);

【讨论】:

  • @ceferrari...如上所述,我们已经有了解决方案,支持您使用我已经使用的 lambda 表单。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-26
相关资源
最近更新 更多