Что означает основной конец ассоциации в отношении 1: 1 в структуре Entity - PullRequest
261 голосов
/ 30 июня 2011
public class Foo
{
    public string FooId{get;set;}
    public Boo Boo{get;set;}
}


public class Boo
{
    public string BooId{get;set;}
    public Foo Foo{get;set;}
}

Я пытался сделать это в Entity Framework, когда получил ошибку:

Невозможно определить основной конец ассоциации между типами 'ConsoleApplication5.Boo' и 'ConsoleApplication5.foo.Основной конец этой ассоциации должен быть явно сконфигурирован с использованием API-интерфейса, обеспечивающего свободное взаимодействие или аннотации данных.

Я видел вопросы о StackOverflow с решением этой ошибки, но я хочу понять,что означает термин "основной конец".

Ответы [ 3 ]

371 голосов
/ 30 июня 2011

В отношении «один к одному» один конец должен быть главным, а второй конец - зависимым. Основной конец - это тот, который будет вставлен первым и может существовать без зависимого. Зависимый конец - это тот, который должен быть вставлен после принципала, поскольку он имеет внешний ключ к принципалу.

В случае структуры сущности FK в зависимом также должен быть его PK, поэтому в вашем случае вы должны использовать:

public class Boo
{
    [Key, ForeignKey("Foo")]
    public string BooId{get;set;}
    public Foo Foo{get;set;}
}

или беглое отображение

modelBuilder.Entity<Foo>()
            .HasOptional(f => f.Boo)
            .WithRequired(s => s.Foo);
178 голосов
/ 21 сентября 2012

Вы также можете использовать атрибут аннотации данных [Required] для решения этой проблемы:

public class Foo
{
    public string FooId { get; set; }

    public Boo Boo { get; set; }
}

public class Boo
{
    public string BooId { get; set; }

    [Required]
    public Foo Foo {get; set; }
}

Foo требуется для Boo.

5 голосов
/ 14 июля 2016

Это со ссылкой на ответ @Ladislav Mrnka об использовании беглого API для настройки отношения один-к-одному.

Была ситуация, когда FK of dependent must be it's PK было невозможно.

Например, Foo уже имеет отношение один-ко-многим с Bar.

public class Foo {
   public Guid FooId;
   public virtual ICollection<> Bars; 
}
public class Bar {
   //PK
   public Guid BarId;
   //FK to Foo
   public Guid FooId;
   public virtual Foo Foo;
}

Теперь нам нужно было добавить еще одно отношение-к-одному между Foo и Bar.

public class Foo {
   public Guid FooId;
   public Guid PrimaryBarId;// needs to be removed(from entity),as we specify it in fluent api
   public virtual Bar PrimaryBar;
   public virtual ICollection<> Bars;
}
public class Bar {
   public Guid BarId;
   public Guid FooId;
   public virtual Foo PrimaryBarOfFoo;
   public virtual Foo Foo;
}

Вот как задать отношение один-к-одному, используя свободный API:

modelBuilder.Entity<Bar>()
            .HasOptional(p => p.PrimaryBarOfFoo)
            .WithOptionalPrincipal(o => o.PrimaryBar)
            .Map(x => x.MapKey("PrimaryBarId"));

Обратите внимание, что при добавлении PrimaryBarId необходимо удалить, так как мы указываем его через свободный API.

Также обратите внимание, что имя метода [WithOptionalPrincipal()][1] выглядит довольно иронично.В этом случае Принципал - Бар. WithOptionalDependent () описание в msdn делает его более понятным.

...