Entity framework — определяет соединение, где не требуется ни одна из сторон

#asp.net-mvc #entity-framework-6 #ef-fluent-api

#asp.net-mvc #entity-framework-6 #ef-fluent-api

Вопрос:

У меня проблема, я должен создать модель, в которой у нас есть две сущности, которые МОГУТ быть связаны друг с другом, но также могут существовать как отдельные объекты.

В настоящее время модель выглядит следующим образом:

  public class Authorisation
 {
    public int AuthorisationID { get; set; }

    public virtual Change Change { get; set; }
}


public class Change
{
    public int ChangeID{ get; set; }

    public virtual Authorisation Authorisation { get; set; }

    public int? AuthorisationID{ get; set; }
}
  

Причина этого в том, что у нас может быть запись авторизации, независимая от изменения, и некоторые изменения требуют авторизации, а некоторые нет, поэтому ни одна из сторон отношений не требуется.

Я могу настроить это с помощью fluent API следующим образом:

 modelBuilder.Entity<Authorisation>()
        .HasOptional(t => t.Change)
        .WithOptionalPrincipal(t => t.Authorisation);
  

И все хорошо, за исключением того, что создаваемая миграция выглядит следующим образом

 CreateTable(
            "dbo.Changes",
            c => new
                {
                    ChangeID = c.Int(nullable: false, identity: true),
                    AuthorisationID = c.Int(),
                    Authorisation_AuthorisationID = c.Int(),
                })
            .PrimaryKey(t => t.ChangeID)
            .ForeignKey("dbo.Authorisations", t => t.Authorisation_AuthorisationID)
            .Index(t => t.Authorisation_AuthorisationID);
  

EF решает, что он собирается добавить новый столбец (Authorisation_AuthorisationID), чтобы я мог использовать его в качестве FK между двумя объектами, и я действительно хочу иметь возможность использовать это изменение.Свойство AuthorisationID как FK для авторизации, я не могу найти способ настроить это вообще (пожалуйста, обратите внимание, что мне нужно, чтобы FK был в модели — для согласованности с остальной частью приложения больше, чем что-либо еще).

Подводя итог, мне нужно иметь возможность создавать отношения между двумя объектами, где обе стороны отношений являются необязательными, и, если возможно, я хочу иметь возможность самостоятельно определять столбец FK.

Я просто неправильно подхожу к этому? Я так долго смотрел на один и тот же блок кода, что мог упустить что-то простое.

Комментарии:

1. Чтобы уточнить, после небольшого изучения кода и просмотра того, что приложение фактически помещает в базу данных, проблема, с которой я столкнулся, на самом деле больше, чем мне нужно указать FK самостоятельно или, по крайней мере, иметь возможность получить автоматически сгенерированный ключ из экземпляра объекта

Ответ №1:

Похоже, что явное свойство внешнего ключа не поддерживается для one-to-one отношений — нет HasForeignKey свободного API, а также, если вы добавляете ForeignKey атрибут в свойство навигации, вы получаете исключение, в котором говорится, что множественность должна быть * .

Таким образом, единственный выбор, который у вас есть, — удалить явное Change.AuthorisationID свойство и работать только со свойствами навигации:

Модель:

 public class Authorisation
{
    public int AuthorisationID { get; set; }
    public virtual Change Change { get; set; }
}

public class Change
{
    public int ChangeID{ get; set; }
    public virtual Authorisation Authorisation { get; set; }
}
  

Конфигурация:

 modelBuilder.Entity<Authorisation>()
    .HasOptional(t => t.Change)
    .WithOptionalPrincipal(t => t.Authorisation)
    .Map(a => a.MapKey("AuthorisationID"));
  

Комментарии:

1. Это то, что я подумал. Немного больно, я мог бы обойтись без возможности установить FK для объекта изменения вместо того, чтобы получать авторизацию, но я думаю, что это единственный вариант… Спасибо!