У меня есть следующая таблица:
CREATE TABLE [dbo].[Exception] (
[ExceptionID] INT IDENTITY (1, 1) NOT NULL,
[ParentExceptionID] INT NULL,
[ApplicationID] INT NOT NULL,
[TypeName] VARCHAR (256) NOT NULL,
[Message] VARCHAR (MAX) NULL,
[StackTrace] VARCHAR (MAX) NULL,
[MachineName] VARCHAR (128) NULL,
[UserName] VARCHAR (64) NULL,
[CreatedOn] DATETIME NOT NULL
)
Это используется для хранения исключений, которые происходят в приложениях.У меня есть внешний ключ как таковой:
ALTER TABLE [dbo].[Exception] ADD CONSTRAINT [FK_ParentException_Exception]
FOREIGN KEY ([ParentExceptionID])
REFERENCES [dbo].[Exception] ([ExceptionID])
ON DELETE NO ACTION ON UPDATE NO ACTION;
Почему я разработал его как ParentExceptionID вместо InnerExceptionID, я не могу вам сказать.Это определенно делает его запутанным, моделируя это в EF. Это совершенно произвольно, так как вы можете выразить одни и те же данные в любом случае.
Как вы должны знать, у исключения может быть только одно внутреннее исключение.Однако эта схема позволяет нескольким строкам утверждать, что они имеют один и тот же ParentExceptionID.По логике вещей, этого никогда не происходит, но данные подтверждают это.
Обычно, когда я хочу создать нерекурсивное взаимно-однозначное отношение в моей схеме, я либо использую одно и то же имя столбца первичного ключа в обеих таблицах, либо добавляю уникальный индекс к внешнему ключувторая таблица.
Первая будет выглядеть так:
Table A
PrimaryKey int
[...]
Table B
PrimaryKey int
[...]
Или другим способом:
Table A
PrimaryKeyA int
[...]
Table B
PrimaryKeyB int
PrimaryKeyA int unique references A.PrimaryKeyA
[...]
В любом случае диаграммы SQL и другие инструменты распознают этокак отношения один-к-одному.Entity Framework распознает только первый шаблон, хотя я прочитал.
Моя проблема в том, что с рекурсивным внешним ключом я не могу использовать ни один шаблон.Я, очевидно, не могу иметь первый шаблон, потому что у меня есть только один стол.Я не могу использовать второй, потому что у меня не может быть уникального индекса для столбца внешнего ключа, так как будет более одной строки с NULL ParentExceptionID.Чувак, я бы хотел, чтобы SQL Server позволял уникальному индексу, который не заставлял NULL также быть уникальным!
Когда я пытаюсь создать модель EF из этой схемы, он видит, что несколько строк могут претендовать на один и тот же ParentExceptionIDи это заставляет меня моделировать это как 0..1 -> *
.Я не вижу способа остановить это.У моего объекта Exception есть свойство навигации InnerException, и это коллекция.Понятно, что это не то, что мне нужно.Если я пытаюсь изменить кратность ассоциации и установить ее равной 0..1 Я получаю ошибку сборки:
Кратность недопустима в роли 'InnerException' в отношении 'FK_ParentException_Exception'.Поскольку свойства зависимой роли не являются ключевыми свойствами, верхняя граница кратности зависимой роли должна быть *.
Есть ли способ сделать то, что я хочу?Даже если это означает изменение моей схемы, я мог бы рассмотреть это.Сейчас я думаю, что это невозможно.