Entity Framework создает внешний ключ, ссылаясь на первичный ключ той же таблицы

#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);

    }

}