SQL Server очень консервативен в отношении возможных циклических ссылок или нескольких путей удаления по сравнению с другими базами данных.
Ваш исходящий из нескольких путей удаления к NoteComment:
Delete User -> Note -> NoteComment
Delete User -> NoteComment
Одним из решений является удаление Cascade On Delete for User -> NoteComment и выполнение очистки вручную.
Вы также можете написать триггер базы данных для очистки. Вот пример триггера:
CREATE TRIGGER [dbo].[Users_Delete_Cleanup]
ON [dbo].[Users]
INSTEAD OF DELETE
AS
BEGIN
IF @@ROWCOUNT = 0
RETURN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Delete NoteComment <--> User associations
DELETE nc FROM [dbo].[NoteComment] nc
JOIN DELETED dUser ON dUser.[Id] = nc.[User_Id]
-- Finally, delete user
DELETE u
FROM DELETED dUser
JOIN [dbo].[Users] u ON u.[Id] = dUser.[Id]
END
Правки - дополнительная информация:
Если у вас его еще нет, я настоятельно рекомендую расширение EF Power Tools . Это дает вам возможность щелкнуть правой кнопкой мыши на любом классе, реализующем DbContext, и получить контекстное меню Entity Framework -
Щелкните правой кнопкой мыши свой класс DbContext в Solution Explorer -> Entity Framework -> View DDL SQL
Это даст вам оператор Sql, используемый для генерации всей вашей модели данных - очень полезно, действительно, увидеть, что именно EF думает, что строит. Вы можете попробовать запустить его вручную в SqlServer и немного приблизиться к ошибкам, с которыми он сталкивается. Когда EF создает DDL Sql, если не считать ошибок компиляции, он обычно что-то вам даёт (или совершенно загадочную ошибку нулевой ссылки - затем проверьте окно вывода), но что-то может не работать в SqlServer.
Кроме того, вы можете вручную удалить каскад при удалении для одного-многих отношений с текущей конфигурацией, не нужно указывать ключи, если вы не хотите использовать это свойство:
modelBuilder.Entity<NoteComment>()
.HasRequired<User>(c => c.User)
.WithMany()
.WillCascadeOnDelete(false);