【发布时间】:2021-08-21 00:32:28
【问题描述】:
运行迁移尝试将列从可空更改为非空时遇到错误。我的模型类如下所示:
public class SaleLandNonDeeded
{
public Guid SaleLandNonDeededId { get; set; }
public Guid SaleId { get; set; }
public decimal? TotalValue { get; set; }
public virtual Sale Sale { get; set; }
}
以前,SaleId 的类型为 Guid?。这是DbContext中的模型配置:
modelBuilder.Entity<SaleLandNonDeeded>(entity =>
{
entity.Property(e => e.SaleLandNonDeededId).HasDefaultValueSql("(newid())");
entity.Property(e => e.TotalValue).HasColumnType("money");
entity.HasOne(d => d.Sale)
.WithMany(p => p.SaleLandNonDeeded)
.HasForeignKey(d => d.SaleId)
.HasConstraintName("FK_SaleLandNonDeeded_SaleId");
});
更改类型后,创建了一个新的迁移:
// This line was added manually to delete null values before changing
// the column type.
migrationBuilder.Sql("DELETE FROM SaleLandNonDeeded WHERE SaleId IS NULL");
migrationBuilder.AlterColumn<Guid>(
name: "SaleId",
table: "SaleLandNonDeeded",
type: "uniqueidentifier",
nullable: false,
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"),
oldClrType: typeof(Guid),
oldType: "uniqueidentifier",
oldNullable: true);
这失败了:
Microsoft.EntityFrameworkCore.Database.Command:错误:执行 DbCommand 失败(34 毫秒)[Parameters=[],CommandType='Text',CommandTimeout='30'] 删除索引 [IX_SaleLandNonDeeded_SaleId] ON [SaleLandNonDeeded]; 声明@var1 系统名; 选择 @var1 = [d].[名称] FROM [sys].[default_constraints] [d] 内部连接 [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] WHERE ([d].[parent_object_id] = OBJECT_ID(N'[SaleLandNonDeeded]') AND [c].[name] = N'SaleId'); IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [SaleLandNonDeeded] DROP CONSTRAINT [' + @var1 + '];'); ALTER TABLE [SaleLandNonDeeded] ALTER COLUMN [SaleId] uniqueidentifier NOT NULL; 更改表 [SaleLandNonDeeded] 为 [SaleId] 添加默认值“00000000-0000-0000-0000-000000000000”; 在 [SaleLandNonDeeded] ([SaleId]) 上创建索引 [IX_SaleLandNonDeeded_SaleId]; 抛出异常:System.Private.CoreLib.dll 中的“Microsoft.Data.SqlClient.SqlException” 抛出异常:System.Private.CoreLib.dll 中的“Microsoft.Data.SqlClient.SqlException” 抛出异常:System.Private.CoreLib.dll 中的“Microsoft.Data.SqlClient.SqlException” System.Private.CoreLib.dll 中出现“Microsoft.Data.SqlClient.SqlException”类型的异常,但未在用户代码中处理 无法删除索引“SaleLandNonDeeded.IX_SaleLandNonDeeded_SaleId”,因为它不存在或您没有权限。
模型、上下文、迁移或快照中的任何地方都没有IX_SaleLandNonDeeded_SaleId。在整个解决方案上执行 Ctrl+F 不会返回除上述日志条目之外的匹配项。我不知道为什么 EF Core 试图删除并创建这个索引。我确实在这里发现了一个与此相关的问题:https://github.com/dotnet/efcore/issues/7535,它早在 EF Core 1.0 中就已修复并关闭。我正在使用 EF Core 5.0。
【问题讨论】:
-
如果你已经使用 EF Core 迁移创建了数据库,那么就会有这样的索引,因为 EF Core 会自动为 FK 列添加索引。
-
@IvanStoev 它不是通过迁移创建的。这是一个 15 岁以上的数据库,上下文最初是使用
Scaffold-DbContext创建的。 -
您不能像那样从数据库优先切换到代码优先,因为 EF 代码优先不会跟踪您在 FK 上缺少索引的事实。只需手动更新代码或在更新数据库架构后再次运行 Scaffold-DbContext。
-
不幸的是,EF Core 不仅会自动创建此类索引,而且不允许从模型元数据中删除它们 - 请参阅 stackoverflow.com/questions/63717935/…。并且迁移中没有明确的
DropIndex命令可以手动将其删除。所以......为他们感到羞耻,祝你好运。
标签: c# sql-server entity-framework-core