EF Core 6.0迁移时为新增列设置唯一随机数值默认值的方法
已有表新增唯一随机数值列的实现方案
前提说明
如果要求生成0-10之间的唯一随机数,当表中数据行数超过11时,从数学上无法实现(0-10仅包含11个不同数值)。若数据量大于11,需扩大随机数范围(比如0-100000)才能保证唯一性。
推荐方案:迁移中执行SQL批量处理(适合大量数据)
这种方式直接在数据库端操作,效率远高于C#逻辑处理,适合已有大量数据的表。
步骤1:生成迁移并新增可空列
- 先在对应的实体类中添加目标属性:
public int RandomUniqueNumber { get; set; }
- 执行命令生成迁移文件:
# Package Manager Console Add-Migration AddRandomUniqueNumberColumn # .NET CLI dotnet ef migrations add AddRandomUniqueNumberColumn
- 打开生成的迁移文件,修改
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
相关产品推荐
相关产品推荐

