You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EF Core 6.0迁移时为新增列设置唯一随机数值默认值的方法

已有表新增唯一随机数值列的实现方案

前提说明

如果要求生成0-10之间的唯一随机数,当表中数据行数超过11时,从数学上无法实现(0-10仅包含11个不同数值)。若数据量大于11,需扩大随机数范围(比如0-100000)才能保证唯一性。


推荐方案:迁移中执行SQL批量处理(适合大量数据)

这种方式直接在数据库端操作,效率远高于C#逻辑处理,适合已有大量数据的表。

步骤1:生成迁移并新增可空列

  1. 先在对应的实体类中添加目标属性:
public int RandomUniqueNumber { get; set; }
  1. 执行命令生成迁移文件:
# Package Manager Console
Add-Migration AddRandomUniqueNumberColumn

# .NET CLI
dotnet ef migrations add AddRandomUniqueNumberColumn
  1. 打开生成的迁移文件,修改Up方法里的新增列代码,先设置为可空:
migrationBuilder.AddColumn<int>(
    name: "RandomUniqueNumber",
    table: "YourTableName", // 替换为你的表名
    type: "int",
    nullable: true);

步骤2:添加SQL脚本批量生成唯一随机数

在Up方法中添加SQL脚本,以SQL Server为例,通过随机排序行号生成唯一值:

// 批量更新生成唯一随机数
migrationBuilder.Sql(@"
    WITH NumberedRows AS (
        SELECT 
            Id, 
            RandomUniqueNumber,
            ROW_NUMBER() OVER (ORDER BY NEWID()) AS RowNum
        FROM YourTableName -- 替换为你的表名
    )
    UPDATE NumberedRows
    SET RandomUniqueNumber = (RowNum - 1) % 11; -- 0-10范围,数据量>11时需改为更大范围,比如% 100000
");

// 将列修改为不可空
migrationBuilder.AlterColumn<int>(
    name: "RandomUniqueNumber",
    table: "YourTableName",
    type: "int",
    nullable: false);

// 若数据量≤11,可添加唯一约束(否则跳过)
// migrationBuilder.CreateIndex(
//     name: "IX_YourTableName_RandomUniqueNumber",
//     table: "YourTableName",
//     column: "RandomUniqueNumber",
//     unique: true);

备选方案:C#逻辑生成(仅适合小数据量)

如果必须用C#的Random类生成,仅推荐用于数据量很小的表(≤11行,对应0-10范围),大量数据下效率极低:

protected override void Up(MigrationBuilder migrationBuilder)
{
    // 先新增可空列(代码同推荐方案步骤1)
    migrationBuilder.AddColumn<int>(
        name: "RandomUniqueNumber",
        table: "YourTableName",
        type: "int",
        nullable: true);

    // 使用DbContext处理数据
    using (var context = new YourDbContext(migrationBuilder.GetService<DbContextOptions<YourDbContext>>()))
    {
        var entities = context.YourTable.ToList();
        var random = new Random();
        var usedNumbers = new HashSet<int>();

        foreach (var entity in entities)
        {
            int num;
            // 循环生成直到拿到未使用的数值,数据量超范围会进入死循环
            do
            {
                num = random.Next(0, 11);
            } while (!usedNumbers.Add(num) && usedNumbers.Count < 11);

            entity.RandomUniqueNumber = num;
        }

        context.SaveChanges();
    }

    // 修改列为不可空
    migrationBuilder.AlterColumn<int>(
        name: "RandomUniqueNumber",
        table: "YourTableName",
        type: "int",
        nullable: false);
}

关键注意事项

  • 若要保证绝对唯一,随机数范围必须≥表中数据行数,否则必然出现重复
  • 大量数据场景下,优先选择SQL端处理,避免C#端拉取全量数据的性能问题
  • 若不需要严格的小范围随机,可使用SQL函数生成大范围随机数,比如CAST(ABS(CHECKSUM(NEWID())) % 100000 AS INT),重复概率极低

内容的提问来源于stack exchange,提问作者Amirmahdi Ghodsi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 04:10:34