#sql #entity-framework #entity-framework-6
#sql #entity-framework #entity-framework-6
Вопрос:
Я хочу использовать Entity Framework code-first для создания внешнего ключа путем ссылки на первичный ключ той же таблицы. Пожалуйста, запустите SQL, чтобы понять требование, хотя позвольте мне лучше всего его изложить.
У меня есть User
класс / модель, которая имеет свойство UserId
(первичный ключ), теперь я хочу иметь еще два свойства CreatedBy
, и UpdatedBy
оба в качестве внешнего ключа UserId
для одной и той же User
таблицы
Структура таблицы
UserID(PK,int,not null)
FirstName
LastName
UpdatedBy
CreatedBy(FK,int,not null) -- FK to UserId
UpdatedBy(FK,int, not null) -- FK to UserId
SQL для справки
CREATE TABLE [dbo].[User]
(
[UserId] [int] IDENTITY(1,1) NOT NULL,
[FirstName] [nvarchar](50) NOT NULL,
[LastName] [nvarchar](50) NOT NULL,
[Email] [nvarchar](50) NOT NULL,
[CreatedBy] [int] NULL,
[UpdatedBy] [int] NULL,
CONSTRAINT [PK_tbl_User] PRIMARY KEY CLUSTERED ([UserId] ASC)
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[User] WITH NOCHECK
ADD CONSTRAINT [FK_tbl_User_CreatedBy]
FOREIGN KEY([CreatedBy]) REFERENCES [dbo].[User] ([UserId])
GO
ALTER TABLE [dbo].[User] CHECK CONSTRAINT [FK_tbl_User_CreatedBy]
GO
ALTER TABLE [dbo].[User] WITH NOCHECK
ADD CONSTRAINT [FK_tbl_User_UpdatedBy]
FOREIGN KEY([UpdatedBy]) REFERENCES [dbo].[User] ([UserId])
GO
ALTER TABLE [dbo].[User] CHECK CONSTRAINT [FK_tbl_User_UpdatedBy]
GO
Комментарии:
1. Итак, в чем собственно проблема, с которой вы столкнулись?
2. Я бы сделал CreatedBy и UpdatedBy обнуляемыми, как вы могли бы получить в troulbe с настройкой CreatedBy для первого пользователя. UpdatedBy также может быть null, если обновлений еще нет. Не может указывать на одного и того же пользователя с ограничением not nullable.
3. Сначала покажите нам свой существующий код.
Ответ №1:
Я подозреваю, что ваша проблема связана с ненулевыми внешними ключами.
Вы не сможете добавить нового пользователя, если его не создаст другой пользователь. Итак, как вставить первого пользователя?
Удаление пользователя кажется таким же сложным. Ссылки на внешние ключи должны быть либо равны нулю, либо каскадному удалению. Значение Null не является опцией, поскольку поле ссылки помечено как «not null». Таким образом, команда delete будет каскадироваться, теоретически удаляя все записи из таблицы, в конечном итоге. Вплоть до первого пользователя, который не может быть удален, поскольку нет пользователя, который создал первого пользователя.
Никакая СУБД не будет / не должна допускать такой дизайн базы данных.
public class User {
public int UserId {get; set;}
public string FirstName {get; set;}
public string LastName {get; set;}
public Nullable<int> CreatedByRef {get; set;}
public Nullable<int> UpdatedByRef {get; set;}
public virtual User CreatedBy {get; set;}
public virtual User UpdatedBy {get; set;}
}
public class UserMap : EntityTypeConfiguration<User> {
public UserMap() {
ToTable("Users");
HasKey(t=>t.UserId);
HasOptional(t=>t.CreatedBy).WithMany().HasForeignKey(t=>t.CreatedByRef);
HasOptional(t=>t.UpdatedBy).WithMany().HasForeignKey(t=>t.UpdatedByRef);
}
}