Code First模式下复合键表指定主键排序的技术问题
EF Core Code First复合键表默认排序调整问题
我用Code First模式开发,OrderProductList模型是OrderId和ProductId的复合键,但生成的OrdersList表查询时默认按ProductId排序,想改成按OrderId排序。
相关代码
模型代码
public class OrderProductList { public virtual Order? Order { get; set; } public int OrderId { get; set; } public virtual Product? Product { get; set; } public int ProductId { get; set; } }
上下文配置代码
modelBuilder.Entity<OrderProductList>().HasKey(o => new {o.OrderId,o.ProductId});
自动生成的迁移代码
migrationBuilder.CreateTable( name: "OrdersList", columns: table => new { OrderId = table.Column<int>(type: "int", nullable: false), ProductId = table.Column<int>(type: "int", nullable: false) }, constraints: table => { table.PrimaryKey("PK_OrdersList", x => new { x.OrderId, x.ProductId }); table.ForeignKey( name: "FK_OrdersList_Orders_OrderId", column: x => x.OrderId, principalTable: "Orders", principalColumn: "Id", onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "FK_OrdersList_Products_ProductId", column: x => x.ProductId, principalTable: "Products", principalColumn: "Id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateIndex( name: "IX_OrdersList_ProductId", table: "OrdersList", column: "ProductId");
问题定位与解决
检查后发现,自动生成的迁移里额外创建了IX_OrdersList_ProductId索引,这是导致查询默认按ProductId排序的关键原因——查询优化器会优先使用这个单列索引来排序。
解决步骤:
- 先创建一个空迁移,用来调整索引:
终端命令:dotnet ef migrations add AdjustOrdersListIndex
或者Package Manager Console命令:Add-Migration AdjustOrdersListIndex - 在生成的空迁移类里,写入移除旧索引、添加新索引的代码:
// 移除ProductId的单列索引 migrationBuilder.DropIndex( name: "IX_OrdersList_ProductId", table: "OrdersList"); // 添加OrderId的单列索引 migrationBuilder.CreateIndex( name: "IX_OrdersList_OrderId", table: "OrdersList", column: "OrderId");
- 执行迁移更新数据库:
终端命令:dotnet ef database update
或者Package Manager Console命令:Update-Database
另外关于复合键顺序的疑问:复合键new { x.OrderId, x.ProductId }的顺序会影响主键的物理存储顺序,但查询的默认排序主要由查询语句或被优先使用的索引决定,这次的问题和复合键顺序无关,核心是额外生成的ProductId索引。
内容的提问来源于stack exchange,提问作者Islam Alsaadawy
相关产品推荐
相关产品推荐

