因密钥不兼容而无法创建关系

问题描述 投票:0回答:1

我正在尝试创建一个赞成/反对系统,但在尝试创建迁移时遇到错误。 我对 .NET 有点陌生,所以我真的不知道我需要做什么来解决我的问题。

为我返回的错误消息是:

具有外键属性 {'CommentId' : string} 的从 'Vote.Comment' 到 'Comment.Votes' 的关系无法定位主键 {'PostId' : string, 'UserId' : string},因为它不兼容。为此关系配置一个主键或一组具有兼容类型的外键属性。

这是所有必要的代码

  • OnModelCreating函数:
protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        
        {...}     

        #region Posts

        builder.Entity<Post>()
            .HasKey(p => p.UserId);
        
        builder.Entity<Post>()
            .HasOne(p => p.User)
            .WithMany(u => u.Posts)
            .HasForeignKey(p => p.UserId)
            .OnDelete(DeleteBehavior.Restrict);

        builder.Entity<Post>()
            .Property(p => p.Title)
            .HasMaxLength(100);
        builder.Entity<Post>()
            .Property(p => p.Text)
            .HasMaxLength(1500);

        // Comments
        builder.Entity<Comment>()
            .HasKey(c => new { c.PostId, c.UserId });

        builder.Entity<Comment>()
            .HasOne(c => c.User)
            .WithMany(u => u.Comments)
            .HasForeignKey(c => c.UserId)
            .OnDelete(DeleteBehavior.Restrict);
        builder.Entity<Comment>()
            .HasOne(c => c.Post)
            .WithMany(p => p.Comments)
            .HasForeignKey(c => c.PostId)
            .OnDelete(DeleteBehavior.Restrict);

        builder.Entity<Comment>()
            .Property(c => c.CommentText)
            .HasMaxLength(1500);

        // Votes
        builder.Entity<Vote>()
            .HasKey(v => new { v.PostId, v.CommentId });

        builder.Entity<Vote>()
            .HasOne(v => v.User)
            .WithMany(v => v.Votes)
            .HasForeignKey(v => v.UserId);

        builder.Entity<Vote>()
            .HasOne(v => v.Post)
            .WithMany(v => v.Votes)
            .HasForeignKey(v => v.PostId);

        builder.Entity<Vote>()
            .HasOne(v => v.Comment)
            .WithMany(c => c.Votes)
            .HasForeignKey(v => v.CommentId);

        #endregion
    }
  • 应用程序用户类别:
public class AppUser : IdentityUser
{
    public AppUser()
    {
        Follower = new List<FollowUser>();
        Following = new List<FollowUser>();

        Blocker = new List<BlockUser>();
        Blocking = new List<BlockUser>();

        Posts = new List<Post>();
        Comments = new List<Comment>();
    } 
    
    public override string Id { get; set; }
    public required string FullName { get; set; }
    
    // Follow system
    public ICollection<FollowUser> Follower { get; set; }
    public ICollection<FollowUser> Following { get; set; }
    
    //Block System
    public ICollection<BlockUser> Blocker { get; set; }
    public ICollection<BlockUser> Blocking { get; set; }

    // Posting System
    public ICollection<Post> Posts { get; set; }
    public ICollection<Comment> Comments { get; set; }
    
    public ICollection<Vote> Votes { get; set; }

    // Account Settings
    public bool IsPrivate { get; set; } = false;
}
  • PostEntity 类
public abstract class PostEntity
{
    public Guid Id { get; set; }
    public AppUser User { get; set; }
    public string UserId { get; set; }
}
  • 评论课
public class Comment : PostEntity
{
    public Post Post { get; set; }
    public string PostId { get; set; }
    public string CommentText { get; set; }
    public ICollection<Vote> Votes { get; set; }

    public Comment(string userId, string postId, string commentText)
    {
        Id = Guid.NewGuid();
        UserId = userId;
        PostId = postId;
        CommentText = commentText;
    }
}
  • 投票班级
public class Vote
{
    public AppUser User { get; set; }
    public string UserId { get; set; }
    public readonly Post? Post;
    public readonly string? PostId;
    public readonly Comment? Comment;
    public readonly string? CommentId;
    public bool IsUpvote { get; set; }
    
    public Vote(string? postId, string? commentId)
    {
        PostId = postId;
        CommentId = commentId;
    }
}
c# asp.net .net api entity-framework
1个回答
0
投票

可能,您在

OnModelCreating
方法中不需要这个:

builder.Entity<Comment>()
        .HasKey(c => new { c.PostId, c.UserId });

此外,我注意到

Vote
类具有带有
readonly
关键字的属性。尝试摆脱它们并创建一个默认构造函数。我很好奇为什么 ID 是
string
?考虑使用
GUIDs
代替。

这应该是这样的:

public class Vote
{
    public AppUser User { get; set; }
    public Guid UserId { get; set; }

    public Post? Post;
    public Guid? PostId;

    public Comment? Comment;
    public Guid? CommentId;

    public bool IsUpvote { get; set; }
    
    public Vote() {}

    public Vote(string? postId, string? commentId)
    {
        PostId = postId;
        CommentId = commentId;
    }
}

而且我不确定重载的构造函数

public Vote(string? postId, string? commentId)
。你真的需要吗?

此外,您似乎可以删除

OnModelCreating
方法中的一些绑定,因为默认情况下它们是在您的实体中定义的。尝试删除它,例如:

builder.Entity<Vote>()
            .HasOne(v => v.Comment)
            .WithMany(c => c.Votes)
            .HasForeignKey(v => v.CommentId);
© www.soinside.com 2019 - 2024. All rights reserved.