EF modelBuilder 中指定的数据类型与创建的数据类型不对应

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

我使用 EF 创建了数据库表,并希望在 FriendInvites.SenderUserId 之间创建外键 FriendInvites.cs:

public class FriendInvites
{
    [Key]
    public int Id { get; set; }

    //Foreign key to UserInfo userId
    public string SenderUserId { get; set; } = string.Empty;

    //Navigation property
    public UserInfo SenderId { get; set; }

    public string TargetUserId { get; set; } = string.Empty;

    public UserInfo TargetId { get; set; }
}

和 UserInfo.UserId 用户信息.cs:

public class UserInfo
{
    [Key]
    public string UserId { get; set; } = string.Empty;

    [Required]
    public string UserName { get; set; } = string.Empty;


    //Navigation property to GroupInvites
    public ICollection<GroupInvites> GroupInvites;

    //Navigation property to GroupsCreatorsList
    public ICollection<GroupsCreatorsList> CreatorOfGroups;

    //Navigation property to GroupMemberList
    public ICollection<GroupMemberList> GroupMembers;

    public ICollection<FriendInvites> SenderUsers;

    public ICollection<FriendInvites> TargetUsers;
}

然而,它并没有达到预期的效果。我尝试在 SQL Server Management Studio 中创建这个外键,但也失败了。然后我发现这是由于数据类型不匹配造成的; UserInfo.UserId 定义为 nvarchar(450),而 FriendInvites.SenderUserId 定义为 nvarchar(max)。我更改了 SQL Server 中的数据类型,这使我能够成功创建外键。

随后,我尝试在 OnModelCreating() 方法中显式指定数据类型:

modelBuilder.Entity<FriendInvites>()
    .Property(e => e.SenderUserId).HasColumnType("nvarchar(450)");

modelBuilder.Entity<FriendInvites>()
    .Property(e => e.TargetUserId).HasColumnType("nvarchar(450)");

但该列继续创建为 nvarchar(max)。我不确定为什么会发生这种情况,特别是因为之前一切都运行良好(我在引用 UserInfo.UserId 主键的不同表中创建了外键)。”

这是具有 UserInfo.UserId 列外键的其他类的示例:

public class GroupsCreatorsList
{
    [Key]
    public Guid GroupId { get; set; }

    [Required]
    public string GroupName { get; set; } = string.Empty;

    //Foreighn key to UserInfo.UserId
    public string CreatorId { get; set; } = string.Empty;

    //Navigation property to UserInfo
    public UserInfo Creator { get; set; }

    //Navigation property to GroupInvites
    public ICollection<GroupInvites> GroupInvites { get; set; }

    //Navigation property to GroupMemberList
    public ICollection<GroupMemberList> GroupMembers { get; set; }
}

这是外键的设置:

modelBuilder.Entity<UserInfo>()
    .HasMany(e => e.CreatorOfGroups)
    .WithOne(e => e.Creator)
    .HasForeignKey(e => e.CreatorId)
    .IsRequired();

你建议我做什么?

c# sql-server entity-framework-core foreign-keys
1个回答
0
投票

首先,如果您好奇为什么 EF 选择

NVARCHAR(450)
,那就是关于最大索引长度!

我之前遇到过这个有趣的问题,我在 EF core repo 上创建了一个问题,你可以在这里查看:

https://github.com/dotnet/efcore/issues/31167

简而言之,由于 SQL Server 索引的最大长度为 900 个字符,EF 决定将其中一半设置为 450 个字符,因此 EF 认为该列可能还有另一个复合索引。但您可以使用

HasMaxLength
以编程方式更改长度。

您提到您手动更改了数据库架构来为表设置外键,这是不好的并且会影响 EF 处理迁移。

我的建议是,如果可能的话,恢复有关这些表的最近迁移,并尝试通过在主键和外键上设置 HasMaxLength 来再次创建迁移。

不过,从性能的角度来看,我不喜欢将

string
属性设置为主键。因此,您可以使用
long
设置另一个
IDENTITY(1,1)
列作为 ID,然后在用户名上放置唯一索引。如果根据你的逻辑可能的话,再一次。

© www.soinside.com 2019 - 2024. All rights reserved.