在Entity Framework Core中建模文件夹结构

我想将分层文件夹结构保存到SQL数据库中。 这堂课是这样的:

public class Folder { public Folder() { Children = new List(); } public string Name { get; set; } public int Id { get; set; } public int? ParentId { get; set; } public Folder Parent { get; set; } public ICollection Children { get; set; } } 

我正在尝试使用Entity Framework Core映射它:

 builder.Entity() .HasKey(i => i.Id); // Relation 1 builder.Entity() .HasMany(e => e.Children) .WithOne(e => e.Parent) .HasForeignKey(e => e.ParentId); // Relation 2 builder.Entity() .HasOne(f => f.Parent) .WithMany(f => f.Children) .OnDelete(Microsoft.EntityFrameworkCore.Metadata.DeleteBehavior.Cascade); 

如果我尝试更新数据库,我会收到以下exception:

System.Data.SqlClient.SqlException:在表’文件夹’上引入FOREIGN KEY约束’FK_Folders_Folders_ParentId’可能会导致循环或多个级联路径。 指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。 无法创建约束或索引。 查看以前的错误。
在System.Data.SqlClient.SqlConnection.OnError(SqlExceptionexception,Boolean breakConnection,Action 1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource
1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource
1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource
1 completion,Boolean sendToPipe,Int32 timeout,Boolean asyncWrite,String methodName)
在System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
在Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection连接,String executeMethod,IReadOnlyDictionary 2 parameterValues, Boolean openConnection, Boolean closeConnection)
at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteNonQuery(IRelationalConnection connection, IReadOnlyDictionary
2 parameterValues, Boolean openConnection, Boolean closeConnection)
at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteNonQuery(IRelationalConnection connection, IReadOnlyDictionary
2 parameterValues, Boolean openConnection, Boolean closeConnection)
at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteNonQuery(IRelationalConnection connection, IReadOnlyDictionary
2 parameterValues,布尔manageConnection)
在Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQuery(IEnumerable`1 migrationCommands,IRelationalConnection连接)
在Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
在Microsoft.EntityFrameworkCore.Design.MigrationsOperations.UpdateDatabase(String targetMigration,String contextType)
在Microsoft.EntityFrameworkCore.Tools.Cli.DatabaseUpdateCommand。 c__DisplayClass0_0.b__0()
在Microsoft.Extensions.CommandLineUtils.CommandLineApplication.Execute(String [] args)
在Microsoft.EntityFrameworkCore.Tools.Cli.Program.Main(String [] args)

ClientConnectionId:f0c08167-fba7-4afa-baf0-45909e9a1f4b
错误号码:1785,状态:0,等级:16

在表’文件夹’上引入FOREIGN KEY约束’FK_Folders_Folders_ParentId’可能会导致循环或多个级联路径。 指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。 无法创建约束或索引。 查看以前的错误。

我也尝试在没有’Relation 2’的情况下映射它,它可以工作,但是当我从数据库加载项目时,它们作为单个项目返回,而未设置Children属性。

存储此类数据的正确方法是什么?

您不需要任何映射配置。 模型定义本身足以用于迁移以生成正确的表结构,该结构将是名为Id的PK字段,以及名为ParentId的可空FK字段。

EF Core中的主要原理与EF 6相同。欲了解更多信息,请访问: http : //www.mikesdotnetting.com/article/255/entity-framework-recipe-hierarchical-data-management