【发布时间】: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