【发布时间】:2020-05-21 09:16:04
【问题描述】:
我在开发过程中将 Entity Framework Core 3.1.0 与 SQL Server Express 一起使用。
我有一个一对一的关系和一个一对多的关系,如下所示:
Relation --> SupplierSettings --< Conditions
所以在Relation 和SupplierSetting 之间我有一对一的关系。在SupplierSetting 和Conditions 之间,我有一对多的关系。
类的摘录是这样的。
public class Relation
{
public string GLN { get; set; }
public string Name { get; set; }
public string Country { get; set; }
}
public class SupplierImportSetting
{
public Relation Supplier { get; set; }
public int SupplierId { get; set; }
public int MinimumMarginPercentage { get; set; }
public bool OnlyImportWithConditions { get; set; }
public ICollection<SupplierCondition> Conditions { get; set; }
}
public class SupplierCondition
{
public SupplierImportSetting SupplierImportSetting { get; set; }
public int SupplierImportSettingId { get; set; }
public string DiscountGroup { get; set; }
public string SupplierTradeItemCode { get; set; }
public string Description { get; set; }
public decimal? Discount1Percentage { get; set; } // 1 = 100%
}
我这样配置我的上下文:
// One to one where Relation is Principal and SupplierImportSetting is dependent.
modelBuilder.Entity<Relation>()
.HasOne<SupplierImportSetting>()
.WithOne(sis => sis.Supplier)
.HasForeignKey<SupplierImportSetting>(sis => sis.SupplierId)
.OnDelete(DeleteBehavior.Cascade);
// One to many with SupplierImportSetting as Principal and SupplierCondition as dependent.
modelBuilder.Entity<SupplierImportSetting>()
.HasMany(sis => sis.Conditions)
.WithOne(c => c.SupplierImportSetting)
.HasForeignKey(c => c.SupplierImportSettingId)
.OnDelete(DeleteBehavior.Cascade);
但我收到此错误:
执行 DbCommand 失败 (11ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
ALTER TABLE [SupplierConditions] 添加约束 [FK_SupplierConditions_SupplierImportSettings_SupplierImportSettingId] 外键 ([SupplierImportSettingId]) 引用 [SupplierImportSettings] ([Id]) ON DELETE CASCADE;
Microsoft.Data.SqlClient.SqlException (0x80131904):在表“SupplierConditions”上引入 FOREIGN KEY 约束“FK_SupplierConditions_SupplierImportSettings_SupplierImportSettingId”可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。 无法创建约束或索引。查看以前的错误。
在 E:\agent1_work\34\s\src\Microsoft.Data.SqlClient\netcore\src\Microsoft 中的 Microsoft.Data.SqlClient.SqlConnection.OnError(SqlException 异常,布尔型 breakConnection,Action
1 wrapCloseInAction) in E:\agent1\_work\34\s\src\Microsoft.Data.SqlClient\netcore\src\Microsoft\Data\SqlClient\SqlConnection.cs:line 15911 wrapCloseInAction) \Data\SqlClient\SqlInternalConnection.cs:第 618 行
at Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action
在 E:\agent1_work\34\s\src\Microsoft.Data.SqlClient\netcore\src\Microsoft\Data\SqlClient\TdsParser 中的 Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)。 cs:第 1169 行
在 Microsoft.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) 在 E:\agent1_work\34\s\src\Microsoft.Data.SqlClient\netcore\src \Microsoft\Data\SqlClient\TdsParser.cs:1719 行
在 E:\agent1_work\34\s\src\Microsoft.Data.SqlClient\netcore\src\Microsoft\Data\SqlClient 中的 Microsoft.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean isAsync, Int32 timeout, Boolean asyncWrite) \SqlCommand.cs:第 2857 行
在 Microsoft.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource1 completion, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry, String methodName) in E:\agent1\_work\34\s\src\Microsoft.Data.SqlClient\netcore\src\Microsoft\Data\SqlClient\SqlCommand.cs:line 13952 parameterValues)
at Microsoft.Data.SqlClient.SqlCommand.ExecuteNonQuery() in E:\agent1\_work\34\s\src\Microsoft.Data.SqlClient\netcore\src\Microsoft\Data\SqlClient\SqlCommand.cs:line 974
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQuery(RelationalCommandParameterObject parameterObject)
at Microsoft.EntityFrameworkCore.Migrations.MigrationCommand.ExecuteNonQuery(IRelationalConnection connection, IReadOnlyDictionary
在 Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQuery(IEnumerable`1 migrationCommands,IRelationalConnection 连接)
在 Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
在 Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(字符串 targetMigration,字符串 contextType)
在 Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabaseImpl(字符串 targetMigration,字符串 contextType)
在 Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.c__DisplayClass0_0.<.ctor>b__0()
在 Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action 动作)ClientConnectionId:3563e9af-ca34-45dc-a3aa-76394f5cfcbd
错误号:1785,状态:0,类:16
在表“SupplierConditions”上引入 FOREIGN KEY 约束“FK_SupplierConditions_SupplierImportSettings_SupplierImportSettingId”可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。 无法创建约束或索引。查看以前的错误。
其实SQL Server 可能是对的,因为当我删除一个Relation 实体时,这会导致级联级联删除。但这就是我想要的。 Relation是principal,所以应该删除其他记录。
所以我想,也许我还需要定义一对一关系的另一种方式。当我将它添加到我的上下文配置中时,迁移运行并没有错误地执行。但是当我检查数据库时,在 SupplierImportSettings 上创建的约束没有 ON DELETE。因此,当我删除 Relation 实体时,不会删除 SupplierImportSettings。这不是我想要的。
// SupplierImportSetting is principal, Relation is dependent.
// Define one to one the other way to disable cascade delete in this direction.
modelBuilder.Entity<SupplierImportSetting>()
.HasOne<Relation>(sis => sis.Supplier)
.WithOne()
.OnDelete(DeleteBehavior.NoAction);
无论我尝试什么,我都无法让 Entity Framework Core 来创建我想要的情况。
【问题讨论】:
-
所示模型没有循环/多级联路径。必须有其他未在此处显示的关系导致它。
-
如果您将此作为答案发布,我本可以接受。我会用更多信息来回答它。
标签: c# .net sql-server entity-framework-core