【EF Core】自增+Guid 表结构设计例子

在自增+Guid 表设计中,Id 自增列作为物理主键,Guid 列作为逻辑主键,这样设计有以下好处(但不限于):

  1. 对用户暴露的实体中,若需要给出 Id,则设置一列 Guid,以保护数据、增加其他数据的不可预测性(防爬)。
  2. 映射表外键的 Id 换成 Guid,这样避免了数据在迁移时,自增 Id 带来的数据校对工作。

下面以【资源-映射-标签】表结构为例。

实体类

ResourceLink

public class ResourceLink
{
    public long Id { get; set; }
    public Guid Guid { get; set; }
    
    public virtual ICollection<ResourceLinkTagMap>? ResourceLinkTagMaps { get; set; }

    public ResourceLink()
    {
        ResourceLinkTagMaps = new List<ResourceLinkTagMap>();
    }
}

ResourceLinkTag

public class ResourceLinkTag
{
    public long Id { get; set; }
    public Guid Guid { get; set; }

    public virtual ICollection<ResourceLinkTagMap>? ResourceLinkTagMaps { get; set; }

    public ResourceLinkTag()
    {
        ResourceLinkTagMaps = new HashSet<ResourceLinkTagMap>();
    }
}

ReourceLinkTagMap

public class ResourceLinkTagMap
{
    public long Id { get; set; }

    public Guid ResourceLinkGuid { get; set; }
    public Guid ResourceLinkTagGuid { get; set; }

    public virtual ResourceLink? ResourceLink { get; set; }
    public virtual ResourceLinkTag? ResourceLinkTag { get; set; }
}

实体配置类

ResourceLinkEntityConfig

public class ResourceLinkEntityConfig : IEntityTypeConfiguration<ResourceLink>
{
    public void Configure(EntityTypeBuilder<ResourceLink> builder)
    {
        builder.Property(e => e.Guid).IsRequired();
        
        // 为 Guid 列增加非聚集索引(IsClustered(false)),加快连接查询速度
        // 唯一索引按需求加
        builder.HasIndex(e => e.Guid).IsUnique().IsClustered(false);
    }
}

ResourceLinkTagEntityConfig

public class ResourceLinkTagEntityConfig : IEntityTypeConfiguration<ResourceLinkTag>
{
    public void Configure(EntityTypeBuilder<ResourceLinkTag> builder)
    {
        builder.Property(e => e.Guid).IsRequired();
        
        builder.HasIndex(e => e.Guid).IsUnique().IsClustered(false);
    }
}

ResourceLinkTagMapEntityConfig

public class ResourceLinkTagMapEntityConfig : IEntityTypeConfiguration<ResourceLinkTagMap>
{
    public void Configure(EntityTypeBuilder<ResourceLinkTagMap> builder)
    {
        builder.Property(e => e.ResourceLinkGuid).IsRequired();
        builder.Property(e => e.ResourceLinkTagGuid).IsRequired();

        // 这里需要显式指定关系(HasOne...WithMany)、外键(HasForeignKey)、主实体的主键(HasPrincipalKey)
        builder.HasOne(e => e.ResourceLink).WithMany(e => e.ResourceLinkTagMaps).HasForeignKey(e => e.ResourceLinkGuid).HasPrincipalKey(e => e.Guid);
        builder.HasOne(e => e.ResourceLinkTag).WithMany(e => e.ResourceLinkTagMaps).HasForeignKey(e => e.ResourceLinkTagGuid).HasPrincipalKey(e => e.Guid);
        
        builder.HasIndex(e => e.ResourceLinkGuid).IsClustered(false);
        builder.HasIndex(e => e.ResourceLinkTagGuid).IsClustered(false);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值